Passport OAuth 认证 解析
本示例在laravel 5.5.*版本下
一. 安装
composer require paragonie/random_compat=~2.0
composer require laravel/passport=~4.0
将 Passport 的服务提供者注册到配置文件 config/app.php 的 providers 数组中:
Laravel\Passport\PassportServiceProvider::class,
Passport 使用服务提供者注册内部的数据库迁移脚本目录,所以上一步完成后,你需要更新你的数据库结构。Passport 的迁移脚本会自动创建应用程序需要的客户端数据表和令牌数据表:
php artisan migrate
接下来,你需要运行 passport:install 命令来创建生成安全访问令牌时用到的加密密钥,同时,这条命令也会创建「私人访问」客户端和「密码授权」客户端:
都需要进行安装
php artisan passport:install
将 Laravel\Passport\HasApiTokens Trait 添加到 App\User 模型中
User模型是框架自带的
namespace App;
use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
}
要在 Providers/AuthServiceProvider
的 boot
方法中调用 Passport::routes
函数。这个函数会注册一些在访问令牌、客户端、私人访问令牌的发放和吊销过程中会用到的必要路由
public function boot()
{
$this->registerPolicies();
Passport::routes();
}
需要将配置文件 config/auth.php
中 api
部分的授权保护项( driver
)改为 passport
。此调整会让你的应用程序在接收到 API 的授权请求时使用 Passport 的 TokenGuard
来处理:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
默认情况下,Passport 发放的访问令牌是永久有效的,不需要刷新。但是如果你想给访问令牌配置一个短一些的有效期,那你就需要用到 tokensExpireIn
和 refreshTokensExpireIn
方法了,上述两个方法同样需要在 Providers/AuthServiceProvider
的 boot
方法中调用:
public function boot()
{
$this->registerPolicies();
Passport::routes();
Passport::tokensExpireIn(Carbon::now()->addDays(15)); #时 分
Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));#时 分
}
二. 密码授权令牌
OAuth2 密码授权机制可以让自有应用基于邮箱地址(用户名)和密码获取访问令牌,自有应用比如你的手机客户端。这样就允许自由应用无需跳转步骤即可通过整个 OAuth2 的授权过程。
如果想要通过密码授权机制来发布令牌,首先你需要创建一个密码授权客户端。
php artisan passport:client --password
也可以使用postman请求
$http = new GuzzleHttp\Client;
$response = $http->post('http://your-app.com/oauth/token', [
'form_params' => [
'grant_type' => 'password',
'client_id' => 'client-id', 通过 php artisan passport:client --password 输入在user表创建的邮箱 就可以生成id和密钥
'client_secret' => 'client-secret',
'username' => 'taylor@laravel.com',
'password' => 'my-password',
'scope' => '',
],
]);
return json_decode((string) $response->getBody(), true);
返回数据
{
"token_type": "Bearer",
"expires_in": 54000,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6Ijc5NzI1ZmMzMWM1YWEyNDZmOWFiYjdiODMwNWY0Y2IyODEzZDQ2YjY4YWJhNTJmMGNkZWM3ODA4ZDI5ZTZiYWFlOGY0N2U4ZDFmNzQzYmNhIn0.eyJhdWQiOiI0IiwianRpIjoiNzk3MjVmYzMxYzVhYTI0NmY5YWJiN2I4MzA1ZjRjYjI4MTNkNDZiNjhhYmE1MmYwY2RlYzc4MDhkMjllNmJhYWU4ZjQ3ZThkMWY3NDNiY2EiLCJpYXQiOjE1NjM0MzAwNTIsIm5iZiI6MTU2MzQzMDA1MiwiZXhwIjoxNTYzNDg0MDUyLCJzdWIiOiIyIiwic2NvcGVzIjpbXX0.2Pn-HITcb6zqg0X4u0lpz4aN8JBZnX9LdTwAW_10UOFxyKzpOpPwtCdBK9xB5CBIftfHHqOm1wsff_6-c9rgi1mnpVdb1ozcZNNoR764hPgiBQ7N5yc4hQMrq3CwUt8IYtZsjo1GWm_O4B6i7oKXiWRyTwok5yBKXbK52jQNxCWkxUAkQMOzI5iEQjok6K-xL1XeInkXK4a5a7_tCCTbp0_EzRCeohobDISG0WslyUbRFNA3LElyJa_vL7aX0Ro_2tC7R9EvFmz23GOn0mPwnsXu2tasFHEhAxXyXiM0U28AHItp34ZNlMKQ7y7QHHHfyyR1GiFr3MeODJOkbZx6FuAp8Wk0BWSCa2REi8-cn1QbdKR1abAZKa7HgLlQxN8vYU4QdIth8AS-XP97tdy-jGTcp6MFJ0zzmrudq2WgJOfKSoVMmUjg6_xFUqqdyD4HeAztqJG5qm2POYAWOlnrH1we2C5CCkGfqlwFljXrPaCB9l10yJkRxd7Y_bOjD297cVTzH0LnvTA74U-otqE_tSRjjlWWdMf5iG1qQT-l8gc8BdcLigCyBWM3eU1XNTqbYVBbLIu1LUh2LrI-XQGjTTTB43OU5pKAnwVsEKPqEKXaUIwf6WuQvI-Eh1i7uvLsl-Yg_3M3Z8MeIFfxx-BRAQw7m9VM4FWmNCZBFSWmJTw",
"refresh_token": "def50200684d443678ee8b18eccc0130715234520466e17fb47e8eabbb7a3ebaf0dc94ac79cd9213fe3d06934b97486a2f3c93e88fed034b983b52dc3614d0aca8d1ccca8671320f68b156c5b8791d273224dbda52a86a271aa96dcdc166245ddbf8838109bd780c8f60f064443f3abd0210cf825a9c0f741c047498dbf683760a0a17b312f6f9252193757dfd6d3849ed200d920ee8f71a433f1a50060464a0ef11e5082b7337bd45f4b685210e42b370364e9e13e2b19cc39d092356096841f55c2264744094a8022716c899b62ce0db3c856963a062626385d9d0a93809e9bc2aac84e8c6cd773566f4b9b05352f6a0aa467713c8ee41a4d1e69b55e76d35bed93c5bd0ee591982460994ab721a07aec155a3016f1626321ff7783567b9df1aac6e78883384afb14a7fffaf1ab7149bb96c88e8702e7b06be6f160523dd7c2a3ec2974b10af72038f74e433d6208a3873ebe2810aa95743a13a1a13efd83be4"
}
刷新令牌
$http = new GuzzleHttp\Client;
$response = $http->post('http://your-app.com/oauth/token', [
'form_params' => [
'grant_type' => 'refresh_token',
'refresh_token' => 'the-refresh-token', #发放令牌的时候会一起返回
'client_id' => 'client-id',
'client_secret' => 'client-secret',
'scope' => '',
],
]);
return json_decode((string) $response->getBody(), true);
保护机制
由于在config/auth.php 将api的驱动改成了passport
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
所以在Http/Kernel.php种
'api' => [
// 'throttle:60,1',\
// 'bindings',\
'auth:api'
],
客户端授权令牌
php artisan passport:client
接下来,要使用这种授权,你首先需要在 `app/Http/Kernel.php` 的 `$routeMiddleware` 变量中添加新的中间件:
use Laravel\Passport\Http\Middleware\CheckClientCredentials;
protected $routeMiddleware = [
‘client’ => CheckClientCredentials::class,
];
获取令牌
$guzzle = new GuzzleHttp\Client;
$response = $guzzle->post('http://your-app.com/oauth/token', [
'form_params' => [
'grant_type' => 'client_credentials',
'client_id' => 'client-id',
'client_secret' => 'client-secret',
'scope' => 'your-scope',
],
]);
return json_decode((string) $response->getBody(), true)['access_token'];
请求接口的时候
$response = $client->request('GET', '/api/user', [
'headers' => [
'Accept' => 'application/json',
'Authorization' => 'Bearer '.$accessToken, #$accessToken 是获取返回的accesstoken
],
]);
php artisan passport:keys 生成两个文件 oauth-private.key oauth-public.key
结语
详细解说:Passport OAuth 认证
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: