gpt4 book ai didi

php - 与所有主要提供商实现单点登录的最佳方式?

转载 作者:IT王子 更新时间:2023-10-29 00:53:50 25 4
gpt4 key购买 nike

我已经对这个主题做了很多研究,并且自己实现了很多解决方案。

包括 OpenID、Facebook Connect(使用旧的 Rest API 和新的 Graph OAuth 2.0 API)、Sign in with twitter(据我所知目前已经升级为完全合格的 OpenID)等等。 .

但我仍然缺少完美的一体化解决方案。

在我的研究过程中,我偶然发现了一些有趣的项目:

但我不想依赖外部供应商,我也想要一个免费的解决方案,所以我在实现方面不受限制。

我还看到开发人员尽职尽责地按照提供商的说明实现一项又一项服务,并为所有内容设置模型和数据库表。

当然这会奏效,但这是一项繁重的工作,并且总是需要开发和更改您的应用程序等。

我正在寻找的是一个抽象层,它将所有服务提取到一个可以集成到我的网站中的标准。一旦出现新服务,我只想添加一个模型来处理该特定提供者的抽象,以便我可以将它无缝集成到我的应用程序中。

或者更好的是,找到一个我可以直接下载的现有解决方案。

理想情况下,此抽象服务应独立于我的应用程序托管,以便它可用于多个应用程序并独立升级。

上述 3 种解决方案中的最后一种从概念上看很有前途。一切都只是移植到一个合成的 OpenID,网站只需要实现 OpenID。

过了一会儿我找到了Django socialauth ,一个基于 python 的 Django Webframework 身份验证系统。但它看起来像上面描述的那样运行,我认为这是 Stackoverflow 使用的同一个登录系统(或者至少是一些修改过的 fork...)。

我下载了它并尝试设置它,看看它是否可以设置为一个独立的解决方案,但我没有运气,因为我也不太喜欢 python。

我喜欢基于 PHP 的解决方案。

所以在这篇长文之后,我的问题恰恰是:

  • 您将如何实现 SSO,有什么比移植所有内容并以 OpenID 作为基础更好的主意吗?
  • 这有什么优点和缺点?
  • 您知道任何现有的解决方案吗?最好是开源的。

我希望这个问题不要太主观,在此先感谢。

更新:我得出的结论是,为 Facebook 构建代理/包装器或您可能称之为的东西,将其移植到 OpenID,使其成为 OpenID 端点/提供者将是最佳选择。所以这正是我所做的。

请看下面我的回答。

我添加了赏金以获得反馈/讨论。也许我的方法不如我目前认为的那么好!

最佳答案

As original author of this answer, I want to note that I regard it as OUTDATED. Since most providers decided to exclusively implement Oauth instead of Openid. Newer Openid services will also likely use openid connect, which is based on oauth. There are good libraries like for example: https://github.com/hybridauth/hybridauth

在讨论了已经存在的答案后,我总结一下:

几乎每个主要的提供商都是一个 openid 提供商/端点,包括 Google、Yahoo、Aol。

其中一些要求用户指定用户名来构造 openid 端点。其中一些(上面提到的)确实有发现 url,其中用户 ID 会自动返回,因此用户只需单击即可。 (如果有人能解释一下技术背景,我会很高兴)

但是,唯一的麻烦是 Facebook,因为他们有 Facebook 连接,在那里他们使用经过调整的 OAuth 版本进行身份验证。

现在我为我的项目所做的是设置一个 openid 提供程序,它使用我的 facebook 应用程序的凭据对用户进行身份验证 - 这样用户就可以连接到我的应用程序 - 并返回一个如下所示的用户 ID:

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;
}

}

它只是第一个工作版本(又快又脏)一些动态的东西是根据我的需要硬编码的。它应该显示如何以及可以做到这一点。如果有人拿起并改进它或重新编写它或其他什么,我很高兴:)

我认为这个问题已经回答了

但我添加赏金只是为了进行讨论。我想知道您对我的解决方案有何看法。

我会将赏金奖励给除此之外的最佳答案/评论。

关于php - 与所有主要提供商实现单点登录的最佳方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4061537/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com