openid / oid-connect
内置身份验证与联盟的OpenID-Connect/OAuth2社交登录
Requires
- guzzlehttp/guzzle: ~5.0
- laravel/framework: ~5.0
This package is not auto-updated.
Last update: 2024-09-18 06:31:57 UTC
README
简介OidConnect是一个用于使用OAuth2/OpenID-Connect进行社交登录的Laravel5组件。它实现了一个真正的联邦模型,用户可能有多个指向同一本地账户的社会提供者。它还允许用户在IDP级别使用的不同本地电子邮件/名称。
它支持开箱即用的功能
- Facebook OAuth2
- Google OpenID-Connect
- Yahoo OAuth2
- Microsoft OAuth2
- LinkedIn OAuth2
- Orange OpenID-Connect
- PayPal OpenID-Connect
- FranceConnect OpenID-Connect
- GitHub OAuth2
- 本地密码
最后但同样重要的是,它支持多个保证级别。允许应用程序根据社交认证的来源或提供的个人资料质量选择信任级别。
- 演示:http://oidconnect.breizhme.net
- 英文视频:http://breizhme.net/en/video-technical
- 法语视频:http://breizhme.net/fr/video-technique
- Dailymotion:http://www.dailymotion.com/fulup-bzh
L5/Socialite:为什么我停止使用Socialite?我使用L5/Socialite开始了我的项目。不幸的是,Socialite有太多的限制。
- 缺乏简单的OO扩展性。添加新的IDP需要编辑核心源组件。改变Socialiste的用户模型几乎是不可能的。通过多个非常小的方法进行设计使得调试过程比应有的更难。
- 薄弱的安全模型。Socialite仅依赖于IDP提供的电子邮件进行本地身份验证。对于认证电子邮件的提供者来说,这可能是可以接受的。但是,它无法与像GitHub这样的提供者一起工作,GitHub允许最终用户选择他们想要的任何电子邮件,而没有任何控制。另一类未解决的问题是与Yahoo或Orange这样的提供者相关的问题,它们不返回用户的电子邮件。
- 不支持OpenID-Connect。通过OID-Connect,我们从IDP那里接收带有授权令牌的用户UID。如果该用户已经在联盟表中已知,那么就没有必要在OAUTH2流中向下移动,因为我们有足够的信息可以直接返回本地用户的ID,而无需请求IDP的Identity API。
安装
-
下载并安装一个全新的Laravel-5发行版
composer create-project 'laravel/laravel' 'yourDirProjectName' dev-develop cd yourDirProjectName composer require 'openid/oid-connect'
注意:使用composer,OidConnect位于./vendors/openid/oid-connect
-
通过传递composer直接从Github安装。如果要使用OidConnect以外的composer,请手动安装OidConnect的依赖项。
在您的L5项目根目录中克隆git源代码目录
git clone https://github.com/fulup-bzh/OidConnect.git
更新您的composer.json
将OidConnect添加到'psr-4'命名空间
"psr-4": { "AppNameSpace": "app/", "OidConnect": "OidConnect/" // 这是您安装OidConnect存档的目录 }
添加"guzzlehttp/guzzle"模块
"require": { "laravel/framework": "~5.0", "guzzlehttp/guzzle": "~5.0", // 这是OAuth2和OpenID所必需的
}, composer dumpautoload # 更新自动加载缓存 composer update # 上传guzzle依赖
注意:使用直接GIT安装,您可以将OidConnect放置在您想要的位置。您甚至可以使用共享目录来保持多个L5项目的同步。
- 可选路由注解以运行示例。
OpenIdConnect 不依赖于注解,但示例使用路由注解。如果您想要直接运行示例,您应该安装 "laravel-annotations",这是 LaravelCollective 包之一。
composer require "laravelcollective/annotations" # http://laravelcollective.com/docs/5.0/annotations
composer update
注意:由于在 Laravel 中注解不再默认验证,您应该运行路由:扫描命令来创建路由 artisan route:scan
-
如果您想使用 Orange 提供者进行测试,请在本地主机上创建一个别名
例如:在您的 /etc/hosts 中 "127.0.0.1 oidconnect.localnet"
-
检查您的基本安装是否正常工作
- 在 /etc/hosts 中添加别名 oidconnect.localnet,指向 127.0.0.1
- 使用 : php -t public -S 127.0.0.1:8080 启动本地服务器
- 在浏览器中指向: http://oidconnect.localnet:8080
注意:如果您只使用 GitHub+Facebook 进行测试,您可以替换 oidconnect.localnet
如果您看到 L5 欢迎页面,您就可以进行下一步了
----- 配置您的分发 ------
警告:如果您通过 composer 直接安装了 OidConnect 而不是从 git 安装。目录 'OidConnect/' 应该替换为 'vendors/openid/oid-connect'
A) 创建一个 SQL 数据库,配置 sqlite 并检查它是否正常工作
-> mysql --user=oiddemo --password='123456' oiddemo
B) 创建 .env 文件 [L5 对配置子目录的说明不够清晰]
APP_ENV=local
APP_DEBUG=true
APP_KEY=123456789 # result of ./artisan key:generate
DB_HOST=localhost
DB_DATABASE=oiddemo
DB_USERNAME=oiddemo
DB_PASSWORD=123456
C) 创建数据库表:federation,用户和电子邮件验证表
最简单的方法是将所有 L5 分发迁移文件替换为 DEMO 中的其中一个。在您的应用程序中,您可能希望有自己的用户存储库组织,但为了使演示尽可能简单,我们使用快捷路径。
rm database/migrations/*
cp OidConnect/Samples/Datebase/2014_1* database/migrations/
./artisan migrate
Migration table created successfully.
Migrated: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_12_09_170132_create_users_table
Migrated: 2014_12_09_180945_create_federation_key_table
Migrated: 2014_12_09_190950_create_check_code_table
D) 更新您的服务提供者和 config/app 中的别名
/*
* Add OidConnect Providers...
*/
'OidConnect\DriverManager\IdpFactoryProvider',
'OidConnect\UserManagement\UserProfileProvider',
'OidConnect\LoaAuth\LoaAuthProvider',
/*
* Optional annotation module used in sample controller for route and middleware annotations
*/
'App\Providers\AnnotationsServiceProvider',
/*
* Add OidConnect Aliases
*/
'IdpFactory' => 'OidConnect\DriverManager\IdpFactoryFacade',
'UserProfile'=> 'OidConnect\UserManagement\UserProfileFacade',
'Auth' => 'OidConnect\LoaAuth\LoaAuthFacade',
/*
* comment out L5 Auth Service provider and Facade Alias
*/
//'Illuminate\Auth\AuthServiceProvider',
//'Auth' => 'Illuminate\Support\Facades\Auth',
No
te: we replace the original L5 Auth module, because OidConnect
inherits from Auth and is 100% backward compatible.
E) 更新中间件。OidConnect 附带一系列标准中间件,用于处理控制器上的 LOA 访问限制。
// In app/Http/kernel.php add following filters after L5 ones
protected $routeMiddleware = [
'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
'guest' => 'xxxxxxx\Http\Middleware\RedirectIfAuthenticated',
'auth.loa0' => 'OidConnect\LoaAuth\Loa00Middleware',
'auth.loa1' => 'OidConnect\LoaAuth\Loa01Middleware',
'auth.loa2' => 'OidConnect\LoaAuth\Loa02Middleware',
'auth.loa3' => 'OidConnect\LoaAuth\Loa03Middleware',
];
F) 从 IDP 身份验证提供者获取 API 密钥。
这可能是最长的一部分。您可能需要检查 Samples/Config/OidConnect.php。选择您喜欢的,并请求一个应用程序密钥。您可以在每个提供者示例的顶部找到开发人员控制台 URL。请注意,只有少数提供者接受使用 localhost 重定向。GitHub 是测试中最简单的一个。Facebook 和 Orange 在开发模式下接受 localhost 重定向。Google 和 Yahoo 不接受 localhost 的重定向。
警告:对于 Orange,您不应该使用 localhost:8080 作为测试的重定向,而应该使用您在 127.0.0.1 的 /etc/hosts 中指向的 oid.localnet:8080。虽然这种别名方法不是强制性的,但 GitHub 和 Facebook 支持它。
完成之后,您的 resources/config/OidConnect.php 文件应该为每个希望使用的提供者都有一个有效的密钥和重定向 URL。
G) 进入 Sample 目录安装:cp Samples/Controllers/* app/Http/Controllers/-. cp -r Samples/Templates/* resources/views/-. cp Samples/Config/* config/.
---- 我们现在可以编写我们的第一个 OpenId Connect 应用程序 ----------------
将两个控制器和模板示例复制到您的 "app" 目录中。请注意,示例控制器使用 "App" 命名空间,您可能想更改这一点。
演示有两个控制器。第一个处理登录,第二个模拟一个需要由 LOA 保护的应用程序控制器。控制器具有非常有限的图形设计,以保持它们尽可能简单。
OidZoneController:这是最简单的一个。每个方法都由一个简单的中间件保护,对应于所需的 LOA 级别。请注意,LOA=0 并不意味着用户未登录,它仅表示我们对他的身份完全没有信心。尽管如此,LOA=0 仍然可以接受在博客上留言或存储用户偏好。当用户访问受保护的页面时,如果没有登录,则需要重定向进行身份验证,没有登录页面是必要的。
警告:我在控制器示例中使用了注解,看起来它们将从L5中移除。除非注解作为外部包重新出现。您可能需要使用L5的旧版本或像以前一样构建路由和中间件。
OidLoginController
__construct: 读取OidConnect配置文件并构建驱动器表。这是一个演示场景。在实际情况中,我们应该为每个IDP有一个控制器。
IdpList()
此方法仅显示一个包含您在配置文件中配置的每个IDP的小表格。请注意,IDP的UID是免费的,但应保持唯一。
Idp-Login
它们都基于相同的模型。Idp-Login URL是您在请求提供商的开发控制台上的API客户端密钥时必须声明的一个。如果您曾经使用过Socialite,那么场景是相同的。
当用户点击由IdpList()生成的'github'链接时,他会重定向到githubLogin()。由于这是一个简单的重定向,因此他不会携带任何授权代码。然后调用getIdpAuthorization()方法,并将用户的浏览器重定向到IDP登录服务,其中包含从config/OidConfig中提取的适当参数。当用户从IDP身份验证服务返回时,他有一个授权代码,控制器调用getIdpSocialUser($request)。这个最后一个方法直接返回一个包含终端用户配置文件以及如果此用户已经联合的本地用户配置文件的socialuser对象。
public function githubLogin (HttpRequest $request) {
// at 1st call user has not the IDP code we redirect for authentication
$hasCode = $request->has('code');
if (!$hasCode) return $this->idpdriver->getIdpAuthorization();
// second call we are returning from IDP and we should have a code
$socialuser = $this->idpdriver->getIdpSocialUser($request);
// we got a social user let's federate and log
return $this->federateAndLog($socialuser);
}
FederateAndLog($socialuser)
此方法将处理3种情况,即getIdpSocialUser()返回的社会用户。
- 社会用户已经联合,在这种情况下我们可以登录。
- 社会用户是新的,但本地用户当前登录。在这种情况下,我们将一个新的联合链接添加到现有的本地用户。
- 社会用户未知且我们没有有效的登录会话。在这种情况下,我们需要请求用户同意,并最终检查其配置文件。此步骤通过set/getUserConsent()完成。
Set/getUserConsent()
第一个方法将序列化并将当前的社会用户推送到会话中。然后它提交一个表单。当用户确认其配置文件并返回getUserConsent()时,它将尝试创建和联合本地/社会用户。如果用户创建成功,此方法将调用userProfile::sendVerificationCode通过电子邮件发送验证码。请注意,根据IDP的LOA,此步骤可能不是必需的。大多数IDP返回验证过的电子邮件。
警告:演示控制器使用L5注解进行路由和中间件。您应在app/RouteServiceProvider中声明两个控制器,并应用"php artisan route:scan"以构建路由并在使用前进行筛选。
protected $scan = [
'App\Http\Controllers\OidZonesController',
'App\Http\Controllers\OidLoginController',
];
邮件:演示将尝试向新用户发送验证邮件。如果您没有正确配置resources/config/mail,则此部分将失败。或者,您可以在Login控制器中注释掉userProfile::sendVerificationCode行。
关于SSL和登录的说明。一些提供者将拒绝您在没有从有效的SSL URL访问时登录。出于测试目的,这应该是一个问题,但在上线时可能会。有关如何安装自签名证书的帮助,您可以查看https://laracasts.com/discuss/channels/general-discussion/curl-error-60-ssl-certificate-problem-unable-to-get-local-issuer-certificate
------------- 扩展OidConnect --------------------------------- OidConnect应该很容易扩展。
LOA中间件,创建一个扩展LoaAclMiddleware的类。
创建新的提供商,构建一个继承自 _DriverSuperClass 的提供商,并在 resources/config/OidConnect 中声明您的新的提供商。您不需要在 OidConnect 命名空间中,您的自定义可以保持100%独立于 OidConnect 代码。对于 OAuth2 提供商,您可以参考 Facebook 或 LinkedIn。对于原生的 OpenIdConnect,您应使用 Google 或 Orange。Orange 是我实现 OpenIdConnect 的参考平台。
我希望我没有写得过长,并且您没有在我的 README 中迷失方向。