da ich schon recht lange Zeit nichts mehr mit PHP gemacht habe und hier viel zu wenig Release, hab ich mich mal an nem Facebook Auto-Login/Register versucht.
Zuerst eine kurze Erklärung zu den Dateien im Anhang:
base_login.php
PHP Code:
<?php
require(dirname(__FILE__).'/ez_sql_core.php');
require(dirname(__FILE__).'/ez_sql_mysql.php');
class Base_Login
{
protected $member_uri = 'member.php';
protected $home_uri = 'index.php';
protected $db;
protected $Session;
private $avatar_path = dirname(dirname(__FILE__)).'/images/avatar/'; //Pfad zum Ordner wo die Avatare gespeichert werden.
private $days_update = 7; //Nach wievielen Tagen sollen die Info's vom User upgedatet werden?
public function __construct($db_user, $db_password, $db_name, $db_host)
{
//Überprüft ob der User bereits eingeloggt ist.
if (!isset($_SESSION['user'])) {
$this->db = new ezSQL_mysql($db_user, $db_password, $db_name, $db_host);
} else {
//Wenn ja, dann leite Ihn auf die Member Seite weiter.
$this->Redirect($this->member_uri);
}
}
//Berechne die differenz von zwei Datetime / Timestamp Daten. Gibt den Unterschied in Tagen zurück.
private function dateDiff($time1, $time2)
{
if (!is_int($time1)) {
$time1 = strtotime($time1);
}
if (!is_int($time2)) {
$time2 = strtotime($time2);
}
if ($time1 > $time2) {
$temp = $time1;
$time1 = $time2;
$time2 = $temp;
}
$diff = $time2 - $time1;
return floor($diff / (60 * 60 * 24));
}
//Echte IP vom User bekommen. (Nur bei relativ schlecht eingestellten Proxy's)
private function getIP()
{
if (isset($_SERVER['HTTP_CLIENT_IP'])) {
return $_SERVER['HTTP_CLIENT_IP'];
} elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
return $_SERVER['HTTP_X_FORWARDED_FOR'];
} elseif (isset($_SERVER['HTTP_X_FORWARDED'])) {
return $_SERVER['HTTP_X_FORWARDED'];
} elseif (isset($_SERVER['HTTP_FORWARDED_FOR'])) {
return $_SERVER['HTTP_FORWARDED_FOR'];
} elseif (isset($_SERVER['HTTP_FORWARDED'])) {
return $_SERVER['HTTP_FORWARDED'];
} else {
return $_SERVER['REMOTE_ADDR'];
}
}
//Variablen 'entschärfen'.
//Info: Warum werden die Variablen die von Facebook kommen gegen SQLi geschützt?
//Der Name vom User könnte eine SQLi Attacke beinhalten -> Habs getestet und funktioniert wenn man es
// nicht schützt!
private function escapeVariables()
{
$args = func_get_args();
$var = array();
for($i = 0, $total=count($args); $i < $total; $i++)
{
if(is_int($args[$i]))
{
$var[$i] = intval($args[$i]);
}
else if(is_string($args[$i]))
{
$var[$i] = mysql_real_escape_string($args[$i]);
}
}
return $var;
}
//Zu einer bestimmten Seite weiterleiten.
protected function Redirect($url)
{
header('Location: ' . $url);
}
//Avatar vom einer Url downloaden und speichern.
protected function saveAvatar($url, $id)
{
$file = $this->avatar_path . $id . '.jpg';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
$raw = curl_exec($ch);
curl_close($ch);
if (file_exists($file)) {
unlink($file);
}
$fp = fopen($file, 'x');
fwrite($fp, $raw);
fclose($fp);
}
//Setzt die Session damit der User eingeloggt ist.
protected function setSession($id, $uid, $pid, $first_name, $last_name)
{
//TODO: Secure Session Management to prevent session hijacking.
$_SESSION['user']['id'] = $id;
$_SESSION['user']['oauth_uid'] = $uid;
$_SESSION['user']['oauth_provider'] = $pid;
$_SESSION['user']['first_name'] = $first_name;
$_SESSION['user']['last_name'] = $last_name;
}
//Checkt ob der User bereits Registriert ist.
protected function IsRegistered($uid, $pid)
{
$var = $this->escapeVariables($uid, $pid);
return $this->db->get_row("SELECT * FROM users WHERE oauth_provider_id={$var[1]} AND oauth_uid='{$var[0]}'");
}
//Registriert einen User.
protected function Register($pid, $uid, $first_name, $last_name, $email, $gender)
{
$var = $this->escapeVariables($pid, $uid, $first_name, $last_name, $email, $gender);
$this->db->query("INSERT INTO users (oauth_provider_id,oauth_uid,first_name,last_name,email,gender,ip,isAdmin, last_update)
VALUES ({$var[0]},'{$var[1]}','{$var[2]}','{$var[3]}','{$var[4]}','{$var[5]}','{$this->getIP()}',0, Now())");
return $this->db->get_row("SELECT * FROM users WHERE ID={$this->db->insert_id}");
}
//Gibt die Provider ID zurück.
protected function getProviderID($name)
{
$var = $this->escapeVariables($name);
return $this->db->get_var("SELECT id FROM oauth_providers WHERE provider_name='{$var[0]}'");
}
//Updated den User.
protected function Update($pid, $uid, $first_name, $last_name, $email, $gender)
{
$var = $this->escapeVariables($id, $first_name, $last_name, $email, $gender);
$this->db->query("UPDATE users SET first_name='{$var[1]}', last_name='{$var[2]}', email='{$var[3]}',gender='{$var[4]}',last_update=Now() WHERE ID={$var[0]}");
}
//Checkt ob der User upgedatet werden soll.
protected function needUpdate($id)
{
$datetime = $this->db->get_var("SELECT last_update FROM users WHERE ID={$id}");
$days = $this->dateDiff($datetime, time());
if ($days >= $this->days_update){
return true;
}
else{
return false;
}
}
}
?>
facebook_login.php
PHP Code:
<?php
require(dirname(__FILE__).'/facebook.php');
class Facebook_Login extends Base_Login
{
private $facebook;
private $provider_id;
public function __construct($db_user, $db_password, $db_name, $db_host, $app_id, $secret)
{
parent::__construct($db_user, $db_password, $db_name, $db_host);
$this->facebook = new Facebook(array(
'appId' => $app_id,
'secret' => $secret,
'cookie' => true
));
$this->provider_id = $this->getProviderID('facebook');
}
public function Login()
{
$session = $this->facebook->getUser();
//Ist der User in Facebook eingeloggt?
if (!empty($session)) {
try {
//Wenn ja, entweder um berechtigungen Fragen oder Infos holen.
$user = $this->facebook->api('/me');
}
catch (FacebookApiException $e) {
echo $e;
$user = null;
}
if (!empty($user)) {
//Ist der User bereits registriert?
$result = $this->IsRegistered($user['id'], $this->provider_id);
if (empty($result)) {
//Wenn nicht, dann registriere Ihn und speichere seinen Avatar.
$result = $this->Register($this->provider_id, $user['id'], $user['first_name'], $user['last_name'], $user['email'], $user['gender']);
$this->saveAvatar($this->getAvatarUrl($user['id']), $this->provider_id, $user['id']);
} else {
//Sollen die Infos / Avatar vom User upgedatet werden?
if ($this->needUpdate($result->ID)) {
//Wenn ja, update und speichere seinen Avatar.
$this->Update($result->ID, $user['first_name'], $user['last_name'], $user['email'], $user['gender']);
$this->saveAvatar($this->getAvatarUrl($user['id']), $result->ID);
}
}
//Setze eine Session und leite ihm zur Member Page weiter.
$this->setSession($result->ID, $result->oauth_uid, $result->oauth_provider_id, $result->first_name, $result->last_name);
$this->Redirect($this->member_uri);
} else {
die('There was an error.');
}
} else {
//Schickt den User zum Facebook-Login.
$this->Redirect($this->LoginUrl());
}
}
//Von Facebook die LoginUrl bekommen.
private function LoginUrl()
{
return $this->facebook->getLoginUrl(array('scope' => 'email'));
}
//Echten Link zum Facebook Avatar bekommen.
private function getAvatarUrl($uid)
{
$headers = get_headers('http://graph.facebook.com/' . $uid . '/picture?type=large', 1);
if (isset($headers['Location'])) {
return $url = $headers['Location'];
}
else{
return false;
}
}
}
?>
1. Eine neue Datenbank anlegen und die SQL-Datei importieren.
2. aufrufen und eine neue App erstellen. Display Name, App Domains und bei 'Website with Facebook Login' Adresse der Webseite ausfüllen.
3. AppID & Secret von der App kopieren.
4. In der config.php Datei die benötigten Felder ausfüllen.
5. Auf nen Server hochladen, oder local über xampp. (Achtung, die Domain was auf Facebook angegeben wurde, muss mit der übereinstimmen wo die Seite läuft)
5.1. Um es auf dem localhost zu überprüfen, müsst ihr in xampp einen neuen vhost anlegen, z.B. localhost.com(diese 'Domain' muss dann auch bei Facebook eingetragen werden). Und in der Windows-Host Datei muss ein Eintrag gesetzt werden: '127.0.0.1 localhost.com'
6. Fertig