Ответ 1
Как оригинальный автор этого ответа, я хочу отметить, что я рассматриваю его как Устаревшие. Поскольку большинство провайдеров решило исключительно реализовать Oauth вместо Openid. Более новые услуги Openid также, вероятно, будут использовать openid connect, основанный на oauth. Есть хорошие библиотеки, например, например: https://github.com/hybridauth/hybridauth
После обсуждения уже существующего ответа подытожим:
Практически каждый крупный поставщик - это провайдер/конечная точка openid, включая Google, Yahoo, Aol.
Некоторые из них заставляют пользователя указывать имя пользователя для создания конечной точки openid. Некоторые из них (упомянутые выше) имеют открытые URL-адреса, где идентификатор пользователя автоматически возвращается, так что пользователю нужно только щелкнуть. (я был бы рад, если бы кто-то мог объяснить технический фон)
Однако единственной болью в заднице является Facebook, потому что у них есть Facebook-соединение, где они используют адаптированную версию OAuth для аутентификации.
Теперь то, что я сделал для моего проекта, - это настроить провайдера openid, который аутентифицирует пользователя с учетными данными моего приложения facebook - поэтому пользователь подключается к моему приложению - и возвращает идентификатор пользователя, который выглядит следующим образом:
http://my-facebook-openid-proxy-subdomain.mydomain.com/?id=facebook-user-id
Я также настроил его, чтобы получить адрес и имя электронной почты и вернуть его как атрибуты AX.
Итак, мой сайт просто должен реализовать opend id, и я в порядке:)
Я создаю его для классов, которые вы можете найти здесь: http://gitorious.org/lightopenid
В моем файле index.php я просто вызываю его так:
<?php
require 'LightOpenIDProvider.php';
require 'FacebookProvider.php';
$op = new FacebookProvider;
$op->appid = 148906418456860; // your facebook app id
$op->secret = 'mysecret'; // your facebook app secret
$op->baseurl = 'http://fbopenid.2xfun.com'; // needs to be allowed by facebook
$op->server();
?>
и исходный код FacebookProvider.php следует:
<?php
class FacebookProvider extends LightOpenIDProvider
{
public $appid = "";
public $appsecret = "";
public $baseurl = "";
// i have really no idea what this is for. just copied it from the example.
public $select_id = true;
function __construct() {
$this->baseurl = rtrim($this->baseurl,'/'); // no trailing slash as it will be concatenated with
// request uri wich has leading slash
parent::__construct();
# If we use select_id, we must disable it for identity pages,
# so that an RP can discover it and get proper data (i.e. without select_id)
if(isset($_GET['id'])) {
// i have really no idea what happens here. works with or without! just copied it from the example.
$this->select_id = false;
}
}
function setup($identity, $realm, $assoc_handle, $attributes)
{
// here we should check the requested attributes and adjust the scope param accordingly
// for now i just hardcoded email
$attributes = base64_encode(serialize($attributes));
$url = "https://graph.facebook.com/oauth/authorize?client_id=".$this->appid."&redirect_uri=";
$redirecturl = urlencode($this->baseurl.$_SERVER['REQUEST_URI'].'&attributes='.$attributes);
$url .= $redirecturl;
$url .= "&display=popup";
$url .= "&scope=email";
header("Location: $url");
exit();
}
function checkid($realm, &$attributes)
{
// try authenticating
$code = isset($_GET["code"]) ? $_GET["code"] : false;
if(!$code) {
// user has not authenticated yet, lets return false so setup redirects him to facebook
return false;
}
// we have the code parameter set so it looks like the user authenticated
$url = "https://graph.facebook.com/oauth/access_token?client_id=148906418456860&redirect_uri=";
$redirecturl = ($this->baseurl.$_SERVER['REQUEST_URI']);
$redirecturl = strstr($redirecturl, '&code', true);
$redirecturl = urlencode($redirecturl);
$url .= $redirecturl;
$url .= "&client_secret=".$this->secret;
$url .= "&code=".$code;
$data = $this->get_data($url);
parse_str($data,$data);
$token = $data['access_token'];
$data = $this->get_data('https://graph.facebook.com/me?access_token='.urlencode($token));
$data = json_decode($data);
$id = $data->id;
$email = $data->email;
$attribute_map = array(
'namePerson/friendly' => 'name', // we should parse the facebook link to get the nickname
'contact/email' => 'email',
);
if($id > 0) {
$requested_attributes = unserialize(base64_decode($_GET["attributes"]));
// lets be nice and return everything we can
$requested_attributes = array_merge($requested_attributes['required'],$requested_attributes['optional']);
$attributes = array();
foreach($requested_attributes as $requsted_attribute) {
if(!isset($data->{$attribute_map[$requsted_attribute]})) {
continue; // unknown attribute
}
$attributes[$requsted_attribute] = $data->{$attribute_map[$requsted_attribute]};
}
// yeah authenticated!
return $this->serverLocation . '?id=' . $id ;
}
die('login failed'); // die so we dont retry bouncing back to facebook
return false;
}
function get_data($url) {
$ch = curl_init();
$timeout = 5;
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
}
Его просто первая рабочая версия (быстрая и грязная) Некоторые динамические вещи жестко привязаны к моим потребностям. Он должен показать, как и что это можно сделать. Я счастлив, если кто-то подхватит и улучшит его или напишет его или что-то еще:)
Ну, я считаю, что этот вопрос ответил
но я добавляю щедрость, чтобы обсудить. Я хотел бы знать, что вы думаете о моем решении.
Я награду за награду лучшим ответом/комментарием рядом с этим.