通过 Passport 实现 API 请求认证:隐式授权令牌


后端系统设置

隐式授权令牌和通过授权码获取令牌有点类似,不过,它不需要获取授权码,就可以将令牌返回给客户端,通常适用于同一个公司自有系统之间的认证,尤其是客户端应用不能安全存储令牌信息的时候。

要启用该授权,需要在后端系统 AuthServiceProviderboot 方法中调用 enableImplicitGrant 方法:

public function boot()
{
    ...

    // 启用隐式授权令牌
    Passport::enableImplicitGrant();
}

启用隐式授权之后开发者就可以通过对应应用的 ClientID 从应用中请求访问令牌,还是老规矩,我们先在后端系统 blog 中注册前端应用 testapp

我们将用户ID字段留空,设置应用名称及授权成功后的回调地址。这条 Artisan 命令会在 oauth_clients 表中新增一条记录。

前端应用设置

在前端应用 testapp 中,首先需要在 .env 环境配置中修改 CLIENT_IDCLIENT_SECRET 配置值:

CLIENT_ID=13
CLIENT_SECRET=GDTgIeNVsQ5tPFbok55deciO5My2TSRtv2FYFFHM

config/services.phpblog 配置项中修改 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 中编写 implicitimplicitCallback 方法:

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 实现要更复杂,所以使用场景有限,不过如果在某些安全性要求比较高的场景下,不能在客户端存储令牌信息,则可以选择这种获取令牌的方式访问后端认证接口。


点赞 取消点赞 收藏 取消收藏

<< 上一篇: 通过 Passport 实现 API 请求认证:沙箱测试篇(私人访问令牌)

>> 下一篇: 通过 Passport 实现 API 请求认证:令牌作用域详解