通过 Passport 实现 API 请求认证:隐式授权令牌
后端系统设置
隐式授权令牌和通过授权码获取令牌有点类似,不过,它不需要获取授权码,就可以将令牌返回给客户端,通常适用于同一个公司自有系统之间的认证,尤其是客户端应用不能安全存储令牌信息的时候。
要启用该授权,需要在后端系统 AuthServiceProvider
的 boot
方法中调用 enableImplicitGrant
方法:
public function boot()
{
...
// 启用隐式授权令牌
Passport::enableImplicitGrant();
}
启用隐式授权之后开发者就可以通过对应应用的 ClientID 从应用中请求访问令牌,还是老规矩,我们先在后端系统 blog
中注册前端应用 testapp
:
我们将用户ID字段留空,设置应用名称及授权成功后的回调地址。这条 Artisan 命令会在 oauth_clients
表中新增一条记录。
前端应用设置
在前端应用 testapp
中,首先需要在 .env
环境配置中修改 CLIENT_ID
和 CLIENT_SECRET
配置值:
CLIENT_ID=13
CLIENT_SECRET=GDTgIeNVsQ5tPFbok55deciO5My2TSRtv2FYFFHM
在 config/services.php
的 blog
配置项中修改 callback
配置值:
'callback' => 'http://app.test/auth/implicit/callback'
然后需要在 routes/web.php
里面注册对应的隐式认证路由:
Route::get('/auth/implicit', 'Auth\LoginController@implicit');
Route::get('/auth/implicit/callback', 'Auth\LoginController@implicitCallback');
最后在控制器 LoginController
中编写 implicit
和 implicitCallback
方法:
public function implicit()
{
$query = http_build_query([
'client_id' => config('services.blog.appid'),
'redirect_uri' => config('services.blog.callback'),
'response_type' => 'token',
'scope' => '',
]);
return redirect('http://blog.test/oauth/authorize?'.$query);
}
public function implicitCallback(Request $request)
{
dd($request->get('access_token'));
}
我们在 auth/implicit
路由中发送认证请求到后端系统的 oauth/authorize
路由,如果认证成功会将令牌信息通过传入的 redirect_uri
链接回跳的时候返回。
至此,我们已经编写完了获取隐式授权令牌的业务逻辑。
测试隐式授权认证
下面我们来简单测试下通过隐式授权令牌访问后端认证 API 接口。
首先,我们通过 http://app.test/auth/implicit
获取令牌,访问该链接会跳转到后端应用页面,如果没有登录的话,需要先登录,登录之后会跳转到授权确认页面:
确认授权之后,就会根据当前 URL 中的 redirect_uri
参数值跳转回前端应用,并且在 URL 中附加 access_token
信息:
http://app.test/auth/implicit/callback#access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImUzNWZmOWNjNmU4NzQ0NzQ4OTM4MjFlOGM0NzQ3M2M0YWE3NmQ2MDgyZDJmNTY3NjU3YWU4MmNmNDBmZWJlNzYxYmZjMTg5NDBjMjU2ODJlIn0.eyJhdWQiOiIxMyIsImp0aSI6ImUzNWZmOWNjNmU4NzQ0NzQ4OTM4MjFlOGM0NzQ3M2M0YWE3NmQ2MDgyZDJmNTY3NjU3YWU4MmNmNDBmZWJlNzYxYmZjMTg5NDBjMjU2ODJlIiwiaWF0IjoxNTQ1OTgzMDAxLCJuYmYiOjE1NDU5ODMwMDEsImV4cCI6MTU3NzUxOTAwMSwic3ViIjoiMjAiLCJzY29wZXMiOltdfQ.C6mpRQdUKMHCyULYXMnu6f_WysaV4UbCoiSnPU0Zi8CBj8q5a5pa_CDU_pfnhoDjby7XCwBz6SSUPy6FRf2H0QzBIqMMjc7G39RXcIsLrvVThY5Zagm5EH3iNQ2Odf_qKZtzw9pjv_Y8g07vd8qEMo7wDG5H5yaBVtUvKrE4hb2mb_yZI9v76ievAWZM2ryw8dMbUMrCKZe3Q1FDYf7SiJ7iTxJRBINQYFW5QMBcZy0m8lSnMxS7Xq8WsZ_ZiCdOdCXms17Anfiuba438oxEPtNFZf23Ma4Htp0_oLhejHO9Sz5RXQ8KB7d5SuIwRyCk380TBfv77_OsY3vYBhFtwprZ0tVpZOOAM_qdUKrIbJEVCSGIQaqz8wHjS2WqHkW8I-nVsU8zhewWkFhbeIYAMrqXgPRrljom2u5WAvEwcsHBRe4QxRSN6QwBJiyVLOFWCi6aq_3JmOpDXG8PDlOy2M7DYj4XrkghAvO-FTnpkr_zgoy9ssdRFMzlea5NngdbeDg-QFzma0Jmem253qNXOaN3yS-w15VT4j555UrQXkp2OXS2iuMybYDYlNJExD2QqjHmTHbf2y5YchFTqrBoq00OZ3ASyUxL3w-UzHDjEm8t_oABF6ezsNAIqJVpndy1vHFjb9bfwgYpo7r6i7iizpo_8z0vN64BQowPG-GW9Kk&token_type=Bearer&expires_in=31536000
通过锚点返回 access_token
的原因是不会把它们发送到服务器(你可以无论通过 Laravel 还是PHP 都解析不到 access_token
),只有客户端才能解析上述锚点里的参数。这也正好符合隐式授权令牌的使用场景:客户端凭证不能被安全存储的移动应用或 JavaScript 应用。
在 Postman 中,我们通过上面的 access_token
也可以访问 http://blog.test/api/user
认证接口:
隐式授权令牌也可以用于单页面应用认证 API 接口访问,但是比起我们前面介绍的通过 Cookie 实现要更复杂,所以使用场景有限,不过如果在某些安全性要求比较高的场景下,不能在客户端存储令牌信息,则可以选择这种获取令牌的方式访问后端认证接口。
8 Comments
按照这个文档操作,提示。{"error":"unsupported_grant_type","error_description":"The authorization grant type is not supported by the authorization server.","hint":"Check that all required parameters have been provided","message":"The authorization grant type is not supported by the authorization server."} 不知道怎么回事
学院君指导一下
scope 参数设置为 * 试试
试了,还不行。
是自己生成的 client_id 和 secret 设置到 .env 里面的吗
是的。
能不能远程给我调调
实在不行,我就放弃了。但是做到这里来了。真不想放弃