[ Laravel 从入门到精通 ] 用户认证与授权系列 —— 通过 Passport 实现 API 请求认证:第三方应用篇(授权码获取令牌)

上一篇教程我们主要介绍了公司自有系统之间如何通过用户凭证获取授权码访问认证 API 接口,如果我们自己也是一个开放平台,需要支持第三方应用户接入获取认证信息呢?比如我们常见的第三方应用接入微信登录、微博登录、QQ 登录就是这样的例子。我们把自己的系统比作微信、微博这样的平台,支持第三方 App、网站应用的接入,这个时候如果还像上篇教程介绍的那样访问认证资源,就有安全隐患了,如果第三方应用不可信,把用户名密码信息记录下来,这就泄露了用户的密码数据,肯定是用户和平台都不愿看到的,所以面对这种场景,我们今天介绍另外一种 OAuth 认证方式 —— 通过授权码的方式获取令牌访问认证 API。

这篇教程里,我们把待接入的第三方应用看作前端系统,把自己的平台看作后端系统,跟上篇教程一样,在后端系统注册前端应用后才能处理对前端请求的授权,然后我们在前端系统编写认证视图,用户点击访问认证资源并确认授权后,前端系统才能获取令牌对后端认证 API 接口进行访问。

1、在后端系统注册第三方应用

我们还是在上一篇教程创建的 testapp 应用基础上进行测试,并且在后端系统通过 Artisan 命令 passport:client 新注册这个第三方应用:

学院君注:当然对于大型平台来说,肯定需要设计一整套第三方应用注册、审核流程来完成应用接入。这里简化为通过命令一键注册,原理是一样的,接入方式不同而已。

2、配置第三方应用

接下来,我们回到前端系统,修改 testapp 根目录下 .env 中的 CLIENT_IDCLIENT_SECRET 配置项:

CLIENT_ID=9
CLIENT_SECRET=Xde5hsAbpEU8MMjwELFh6RNOzxX2LsrxgFTZvXkP

config/services.php 中的配置保持和上篇教程一样不变。

3、编写第三方应用路由和控制器

要通过授权码获取访问令牌,需要两步操作,第一步是到后端系统请求授权,如果用户在后端系统没有登录需要先登录,登录之后让用户确认授权,授权之后通过 callback 配置的跳转地址回跳到前端应用,并且在 URL 中带上授权码,然后用户再通过这个授权码获取访问令牌,拿到访问令牌之后就可以请求后端系统认证 API 接口了。

所以,我们需要在前端应用的 routes/web.php 中新增两个路由,一个用于请求授权获取授权码,一个用于从后端应用跳转回来,通过授权码在回跳路由中发起后端请求获取令牌:

Route::get('/auth', 'Auth\LoginController@oauth');
Route::get('/auth/callback', 'Auth\LoginController@callback');

然后定义相应的控制器方法:

public function oauth()
{

    $query = http_build_query([
        'client_id' => config('services.blog.appid'),
        'redirect_uri' => config('services.blog.callback'),
        'response_type' => 'code',
        'scope' => '',
    ]);

    return redirect('http://blog.test/oauth/authorize?'.$query);
}

public function callback(Request $request)
{
    $code = $request->get('code');
    if (!$code) {
        dd('授权失败');
    }
    $http = new Client();
    $response = $http->post('http://blog.test/oauth/token', [
        'form_params' => [
            'grant_type' => 'authorization_code',
            'client_id' => config('services.blog.appid'),  // your client id
            'client_secret' => config('services.blog.secret'),   // your client secret
            'redirect_uri' => config('services.blog.callback'),
            'code' => $code,
        ],
    ]);

    return response($response->getBody());
}

4、测试通过授权码获取令牌

在浏览器中访问 http://app.test/auth,在前端应用中通过后端系统进行授权认证,如果你在后端应用 blog.test 上没有登录,先跳转到登录页面,登录之后则跳转到如下确认授权页面:

点击绿色的授权按钮,就可以跳转到前端应用回调路由,然后发起获取令牌请求获取访问令牌了:

这样,下次从前端应用 app.test 中访问后端系统 API 接口时,就可以通过在请求头中带上 access_token 来获取 blog.test 上的认证资源了,对应的逻辑和上一篇通过密码获取令牌访问是一样的。

通过 Postman 进行测试,将 access_token 值拷贝到下面的 Token 字段,然后发起对认证 API 接口 http://blog.test/api/user 的请求,结果完全一样:

令牌的有效期和刷新逻辑和上一篇密码授权令牌一样,这里也不再赘述了。

下一篇我们将围绕开发平台上入驻的个人开发者授权令牌与认证展开讨论。

学院君 has written 1076 articles

Laravel学院院长,终身学习者

积分:134007 等级:P12 职业:手艺人 城市:杭州

0 条回复

登录后才能进行评论,立即登录?