Laravel Passport 之API授权
我们常常会遇到多账号系统的认证这样的一个应用场景 那么在Laravel中 我们常常会用Passport获取Token来进行密码验证
在Laravel5.3时Taylor就发布了passport的package 用于开发 OAuth 服务端 可以作为Auth验证
其实为什么最近又在整理这个呢 因为我做安卓也有近两个月的时间 期间也接触了不少的客户端的开发 此时我发现再去
研究下laravel的passport的API认证真的会深有体会 之前在写服务端的API只是集成了Dingo和jwt认证 而对于与多账号系统的认证体会不深
所以这几天想写点下来 也会自己以写安卓客户端做更好的服务和认证
这里新建一个项目 以5.3为例
新建完项目之后 开始引入我们的 passport 现在的话应该已经是3.1的版本
可以在composer.json里添加:
"laravel/passport": "^3.0"
在终端执行:
$ composer update
在 app/config/app.php 添加服务:
Laravel\Passport\PassportServiceProvider::class,
当然还需要安装项目依赖(也可以适应yarn):
$ npm install
Passport 使用服务提供者注册内部的数据库迁移脚本目录,所以上一步完成后,你需要更新你的数据库结构。
Passport 的迁移脚本会自动创建应用程序需要的客户端数据表和令牌数据表:
$ php artisam migrate
接下来我们需要运行passport:install 命令来创建生成安全访问令牌时用到的加密密钥
当然这条命令也会创建「私人访问」客户端和「密码授权」客户端(这些解释文档上解释的也很清楚)
$ php artisan passport:install
具体表现在oauth_clients 这张表会新增两条数据
执行完毕后在User Model了添加HasApiTokens 这个 Trait 这会为我们提供一些辅助函数
class User extends Authenticatable
{
use HasApiTokens,Notifiable;
}
接着我们在 AuthServiceProvider 服务中添加路由方法(函数会注册一些发放令牌等一些必要的路由)
public function boot()
{
$this->registerPolicies();
Passport::routes();
}
需要的话可以执行
php artisan route:list这些路由在之后也会用到
最后还得需要在config/auth.php中将api的驱动配置为passport 这样的话我们的api请求时会使用
Passport的TokenGuard
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
]
我们可以注册一个用户接下来 可以使用Laravel自带的 auth登录注册
$ php artisan make:auth
这样访问首页 去注册一个账号
为了使用这些api 我们可能需要一些前端代码 当然在passport中也预定了一些vue组件 我们如果嫌麻烦直接使用他所提供的
$ php artisan vendor:publish --tag=passport-components
使用这些组件时 我们需要去注册这些组件 在app.js中添加给我们的组件
Vue.component(
'passport-clients',
require('./components/passport/Clients.vue')
);
Vue.component(
'passport-authorized-clients',
require('./components/passport/AuthorizedClients.vue')
);
Vue.component(
'passport-personal-access-tokens',
require('./components/passport/PersonalAccessTokens.vue')
);
接下来就是去模板中使用客户端的访问和私人令牌
<passport-clients></passport-clients>
<passport-authorized-clients></passport-authorized-clients>
<passport-personal-access-tokens></passport-personal-access-tokens>
我们会看到创建客户端和 assess token

我们可以去创建一个客户端 因为我们的数据要为很多的客户端服务 如果一个客户端需要访问我们的数据我们就可以为他创建一个客户端
其实这样的应用场景可以想象的就是 当我们比如安卓的app需要使用服务端的数据 可能多个app会使用到同一组数据
那么为了辨识 我们就需要为每个客户端创建一个client 并提供一个回调地址
如果做过第三方授权的就知道了 无论我们是做分享还是授权登陆 我们需要为我们这个客户端提供appID,回调地址
所以这里我们可以先去创建一个客户端
应户名就为codespace 回调url为:http://laravel-passport.dev/callback
创建完成之后就会给出我们的clientId和clientSecret这些是不是很熟悉 其实我们的服务端为我们生成的也就是客户端所需要的这些id和secret
而这个在数据库中的表现就是oauth_clients表中 生成了对应的客户端数据(也就是我们刚刚所创建的)
接下来就是模拟客户端去发起请求 这里我新建了另一个项目passport-client
进入刚创建的项目 因为之前我们已经创建了一个客户端 那么开发者会使用此客户端的 ID 和密钥向你的应用程序请求一个授权码和访问令牌。
首先,接入应用会将用户重定向到你应用程序的 /oauth/authorize 路由上 在刚创建项目的路由添加
Route::get('/redirect', function () {
$query = http_build_query([
'client_id' => 'client-id',
'redirect_uri' => 'http://example.com/callback',
'response_type' => 'code',
'scope' => '',
]);
return redirect('http://your-app.com/oauth/authorize?'.$query);
});
正如我们所看到的当客户端接受到授权请求你时 会显示默认页面 用户可以取消或者允许 用户确认之后才能重定向到指定的
resirect_uri这和我们平时手机app授权登录是一样的流程 只有用户允许授权了 才会跳转到相应页面
当用户允许操作之后会跳转到对应的redirect_uri那么我们定义的是一个callback
所以我们会增加一个路由
Route::get('callback','OAuthController@oauth');
当然我们还是要去实现这样的回调方法
public function oauth(Request $request)
{
$http = new GuzzleHttp\Client;
$response = $http->post('http://your-app.com/oauth/token', [
'form_params' => [
'grant_type' => 'authorization_code',
'client_id' => 'client-id',
'client_secret' => 'client-secret',
'redirect_uri' => 'http://example.com/callback',
'code' => $request->code,
],
]);
return json_decode((string) $response->getBody(), true);
}
相关代码对照着文档看应该没什么问题
值得注意的是上面的客户端和服务端的访问地址根据每个人所定义的地址 在这里我们需要修改的是我们客户端
拿到的client_id和client_secret这是我们开发者在开发客户端都可以拿得到的 填写上我们之前创建客户端所生成的值就行
既然有了这些信息 客户端就可以发起请求 我们访问oauth这个路由 这样应该会跳转到服务端的授权页面

这个过程和我们平时的无论是web端还是移动端的授权是一样的 也就是不同的客户端拿到指定的客户端key之后访问到的服务端的内容
这个时候我们点击授权的话就会跳转到callback这个url这里 也就相当于一个回调地址
我们已经在callback写了我们客户端的处理内容 如果执行到的话我们应该会得到一个access_token
当然授权之后我们也可以拿到一个refresh_token
我们有了这个access_token 就可以去请求我们的api数据了 还记得一开始我们就修改了我们api的driver为passport
所以我们理所当然的得用这个access_token去请求我们需要的数据
其中在api.php这个路由文件中已经默认为我们创建了一个关于用户的api 简单来说就去拿到我们之前注册的用户数据好了
所以在用postman去访问这个http:///your-server.com/api/user时 一开始是访问不到的

只有经过之前的授权认证 拿到我们的额access_token 这个时候加上这个参数再去访问这个url时我们就可以成功访问到了用户数据
总结
其实整个的过程就是我们所熟悉的oauth认证过程 服务端创建一个客户端数据 这也就是对应着我们去一些开发平台盛情得到我们的
ID和key等相关信息 这样服务端会存储这个客户端的信息
我们在不同的客户端当然对应着不同的客户端id 我们在客户端如app或者网站去发起客户端的请求
当然这些请求会附带上我们申请得到的ID和key这样服务端平台校验正确后会返回一个授权页面 这时候用户可以选择授权或者取消
试想一下我们平时在网站或者app利用第三方登录时的场景就知道了 当用户给予授权之后
会执行到客户端的回调地址 在这个回调函数中我们会处理自己的逻辑 比如存储用户的基本信息等
当然也会拿到服务端给我们的access_token和refresh_token这也就是我们平常所说的令牌
拿到令牌之后我们就可以对服务端的一些数据进行操作 比如获取一个用户的信息 用户的相关资料等
如果没有这个token的话是无法访问的 因为我们之前配置的就是api的driver为我们的passport
所以相应的访问数据我们是需要拿到这个token的