我想使用我控制的外部OAuth2服务器来验证我的Laravel 5.2应用程序的用户。作为客户端库,我想使用包league/oauth2-client
据我了解,需要实现自定义用户提供程序,但我不确定所有必需步骤的大局。
这个想法是用户向我的Laravel应用程序提供凭据,换句话说,使用client credentials
方法。然后,持有者令牌和刷新令牌存储在客户端。每次客户端发出请求时,令牌都必须由 OAuth 服务器验证。OAuth 服务器还提供一些基本用户信息,如电子邮件和姓名。因此,在我的应用程序中,本地用户和OAuth用户之间必须存在某种链接。这是通过一个简单的表格完成的,例如
+-------------------+
| Users |
+-------------------+
| id | int(10) |
| oauthId | int(10) |
+---------+---------+
首先,我在 laravel.io 按照本指南创建了一个基本的提供程序框架。但在这一点上,我有几个问题:
该方法
retrieveById
应该从 OAuth 服务返回任何用户,还是仅返回允许查看请求颁发者的用户?我的 OAuth 服务器已经对每个用户进行了权限检查。如果
retrieveById
应该返回任何现有用户,那么我在OAuth服务器上的权限检查是否毫无价值?这将是我的架构中的一个缺陷。某些方法必须返回
'Illuminate'Contracts'Auth'Authenticatable
接口的实现。我必须在哪里实现它?这应该是尝试进行身份验证的用户的表示形式吗?如果这应该代表我的模型中的用户,我遇到了一个问题,我不知道getAuthPassword
的返回值,因为此信息在我的 OAuth 服务器上。我该如何解决这个问题?
如您所见,我很难理解事物在整个身份验证过程中如何协同工作。非常感谢您的帮助。
这个想法是用户向我的Laravel应用程序提供凭据,换句话说,使用客户端凭据方法。
您应该使用授权代码授予将用户转发到您的 oauth 服务器
所以
- 授权代码授予将使用在 oauth 服务器上登录的用户。
- 您可以通过
retrieveById
调用返回用户的权限 - 你可以为你不使用的功能添加一些虚假的填充内容。
这是我的例子,
我使用了一个自定义的laravel/socialite提供商来帮助进行客户端路由和其他事情。league/oauth2-client
应该非常相似。
第一个登录重定向看起来像
class LoginController extends Controller
{
public function login(Request $request)
{
return Socialite::driver('custom-oauth')
->scopes(['read-permissions read-name read-email etc'])
->redirect();
}
}
我将用户模型getAuthIdentifier()
更改为从授权代码授予返回的access_token
。例如
class User implements Authenticatable
{
public function getAuthIdentifier()
{
return $this->token;
}
}
我的登录回调看起来像这样。
class LoginController extends Controller
{
public function callback(Request $request)
{
/** @var 'App'User $user */
$user = Socialite::driver('custom-oauth')->user();
Auth::login($user, true);
return redirect()->home();
}
}
Laravel的SessionGuard
将存储该access_token
,您的自定义用户提供程序应使用access_token
retrieveById
回oauth服务器以获取用户信息
然后我的自定义用户提供程序的retrieveById
如下所示。这基本上是命中oauth服务器并请求当前用户信息。 $identifier
= access_token
class CustomUserProvider implements UserProvider
{
public function retrieveById($identifier)
{
try {
return Socialite::driver('custom-oauth')->userFromToken($identifier);
} catch (AuthenticationException $e) {
return null;
}
}
}
我希望这有所帮助