1. 安装
1-1. 进入项目文件夹,引入Laravel Passport
composer require laravel/passport=~4.0
1-2. 运行passport数据库迁移
php artisan migrate
1-3. 运行 passport:install 命令来创建生成安全访问令牌时所需的加密密钥,同时,这条命令也会创建用于生成访问令牌的「个人访问」客户端和「密码授权」客户端
php artisan passport:install
1–4. 将 Laravel\Passport\HasApiTokens Trait 添加到 需要使用认证的(以App\User为例) 模型中,这个 Trait 会给你的模型提供一些辅助函数,用于检查已认证用户的令牌和使用范围:
<?php
namespace App;
use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
...
1–5. 在 AuthServiceProvider 的 boot 方法中调用 Passport::routes 函数。这个函数会注册发出访问令牌并撤销访问令牌、客户端和个人访问令牌所必需的路由:
<?php
namespace App\Providers;
use Laravel\Passport\Passport;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* 应用程序的策略映射。
*
* @var array
*/
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Passport::routes();
}
}
1–6. 将配置文件 config/auth.php 中授权看守器 guards 的 api 的 driver 选项改为 passport。此调整会让你的应用程序在在验证传入的 API 的请求时使用 Passport 的 TokenGuard 来处理:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
1-7. 测试获取token(使用自己的测试域名,client_id及client_secret填写自己创建的密码授权客户端)
$http = new GuzzleHttp\Client;
$response = $http->post('http://your-app.com/oauth/token', [
'form_params' => [
'grant_type' => 'password',
'client_id' => 'client-id',
'client_secret' => 'client-secret',
'username' => 'taylor@laravel.com',
'password' => 'my-password',
'scope' => '',
],
]);
return json_decode((string) $response->getBody(), true);
1-8. 如果以上的每一步操作都没错的话,会得到类似如下结果:
{
"token_type": "Bearer",
"expires_in": 31535999,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjUzYzM5ZjJlN2YxMzI5N2Q5Y2FlZjFkYzVhZDA3NjQxYzU0YWY3OWIyYzFmMGMwYjM5OTFhZjZmNjk3YjdlNGQwZWQxYTYyOGE4MjkzOWRiIn0.eyJhdWQiOiI2IiwianRpIjoiNTNjMzlmMmU3ZjEzMjk3ZDljYWVmMWRjNWFkMDc2NDFjNTRhZjc5YjJjMWYwYzBiMzk5MWFmNmY2OTdiN2U0ZDBlZDFhNjI4YTgyOTM5ZGIiLCJpYXQiOjE1Mjc3Mzc3MDQsIm5iZiI6MTUyNzczNzcwNCwiZXhwIjoxNTU5MjczNzA0LCJzdWIiOiIxIiwic2NvcGVzIjpbInRlc3QiXX0.eTc7-MoB2_5PfKuh6hlN0Vi3-sjLqZ9-N1-YGPvCTjs1oE_P0gmLfI-dsWDDrY9AC5O1jhdshlmB0odnC5Az3GEctAdnqzuVubn5Iq6nHcH4AgD7YJFzAIMXf4KlsyaO3cA7Ohz1Utnv0eHVYA-x01tK9KT0P-Yp63SsZzgtGsXSQgoqOYsy8QmfE4pr54zihBfwvn4s8A_XBO2EXJmYa1r3k3SyQY8dhvxzAg_Ze9CvAtp-v_zwXx6e1PTEdVJyXKXxrIS-7eXtVX01PLvkHZVRbv_HkP3ouJE_a1jzIL_JztpNMtkUOuelV7bz20mzVkVFyP_P4XW8Fm9uIVuivT_OQet1OyhlKv3ORuXVF6sD2fuYEv-Lcc3OVNtxy_80Nl2m4pZCowyf17QnbZhuWbgjmQJrcKfHHhq-yFohb7FGR8meHxgvB-InfU23PINupitFA_G0seuk9lvvXAFArqvkuAyOTP0wBzNHTl4HT4qkM2c2KeZGl8FQ4Jd_hkDMBuAmiNQ8XE7LS1kkwDOaS8hKuMkTps4fNb7gfWaIFa4FfBRm-ZWanVxU61zooxOmajfDPyAYG3_SVkfObSlMGopAiKM6Aly7o78xJGLdCl0Z2aCws3z1k_VZpdv9bmwGzWJpysldcTwyBLyoDfAQP8y7Plxe09bmfus-JkDrWGU",
"refresh_token": "def502003c32f3cdcb5fc33a27235d9effc81318233071fa0be74c69d0ec8bb4e649183d34eb993cd36a6c93c45ea91e47ce835dad785ac595723cbcbd069a86338e80289fc16d8732f26da9db915e7f8fd8f7da5983e426e8180c908ef2e85c7c313c94ebc8f90830362a1fae39bd0c7fa95efd989c85751cabbe5270c8f608ca7f446c51a8c39a6c9ff5600cef8a7417f8c9a3b34b3c25ff7c46160b7e4530f067f0365b451fb0dec42adc40cae3336b7e4028bd8df48f12f5de0444963ab05099dd15394f24d0986f894ea66e7755f7e29c92c18fe70ab0134673a8dae8ecaa6d05becf529ff281359b487eedef0686646057e84971eb83347c90b7f402010ae662aec7482c750627bac790971db12382e3d55851a454407db608d23707eb23a50bdfab5e8e273a0e67d446ed667c4a12fddc5082a1557eb3bef2353f8a152e5804ab919772529e2f455fb8a1821b53726d6b7b24aaf2d14f72648f3d698810f24557c3"
}
2. 多用户登录
2–1. 引入multiauth扩展包
composer require smartins/passport-multiauth
2–2. 以企业和机构为例, 创建数据模型并覆盖findForPassport方法(用于修改默认验证字段)。未使用常见的username字段。如企业用户名字段tel
<?php
namespace App\Models;
use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Company extends Authenticatable
{
use HasApiTokens, Notifiable;
/**
* 修改认证时的默认username字段为tel
*/
public function findForPassport($username) {
return $this->where('tel', $username)->first();
}
}
2–3. 配置文件 config/auth.php 中 providers 数组增加对应的模型
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'companys' => [
'driver' => 'eloquent',
'model' => App\Models\Company::class,
],
],
2–3. 在文件 app/Http/Kernelmiddlewares的$middlewareGroups中,注册自定义的PassportCustomProvider和PassportCustomProviderAccessToken
class Kernel extends HttpKernel
{
...
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
'custom-provider',
],
'custom-provider' => [
\SMartins\PassportMultiauth\Http\Middleware\AddCustomProvider::class,
\SMartins\PassportMultiauth\Http\Middleware\ConfigAccessTokenCustomProvider::class,
]
];
...
}
2–4. 在 AuthServiceProvider 增加 access token 对应的 passport routes
use Route;
use Laravel\Passport\Passport;
class AuthServiceProvider extends ServiceProvider
{
...
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Passport::routes();
Route::group(['middleware' => 'api'], function () {
Passport::routes(function ($router) {
return $router->forAccessTokens();
});
});
}
...
}
2–5. 测试Company的登录,在参数里面增加provider=companys(对应2-3中添加的provider),注:帐号和密码以自己实际为准
$http = new GuzzleHttp\Client;
$response = $http->post('http://your-app.com/oauth/token', [
'form_params' => [
'grant_type' => 'password',
'client_id' => 'client-id',
'client_secret' => 'client-secret',
'username' => 'username',
'password' => 'password',
'scope' => '',
'provider' => 'companys'
],
]);
return json_decode((string) $response->getBody(), true);
2-6. 如果以上的每一步操作都没错的话,会得到类似如下结果:
{
"token_type": "Bearer",
"expires_in": 31535999,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjUzYzM5ZjJlN2YxMzI5N2Q5Y2FlZjFkYzVhZDA3NjQxYzU0YWY3OWIyYzFmMGMwYjM5OTFhZjZmNjk3YjdlNGQwZWQxYTYyOGE4MjkzOWRiIn0.eyJhdWQiOiI2IiwianRpIjoiNTNjMzlmMmU3ZjEzMjk3ZDljYWVmMWRjNWFkMDc2NDFjNTRhZjc5YjJjMWYwYzBiMzk5MWFmNmY2OTdiN2U0ZDBlZDFhNjI4YTgyOTM5ZGIiLCJpYXQiOjE1Mjc3Mzc3MDQsIm5iZiI6MTUyNzczNzcwNCwiZXhwIjoxNTU5MjczNzA0LCJzdWIiOiIxIiwic2NvcGVzIjpbInRlc3QiXX0.eTc7-MoB2_5PfKuh6hlN0Vi3-sjLqZ9-N1-YGPvCTjs1oE_P0gmLfI-dsWDDrY9AC5O1jhdshlmB0odnC5Az3GEctAdnqzuVubn5Iq6nHcH4AgD7YJFzAIMXf4KlsyaO3cA7Ohz1Utnv0eHVYA-x01tK9KT0P-Yp63SsZzgtGsXSQgoqOYsy8QmfE4pr54zihBfwvn4s8A_XBO2EXJmYa1r3k3SyQY8dhvxzAg_Ze9CvAtp-v_zwXx6e1PTEdVJyXKXxrIS-7eXtVX01PLvkHZVRbv_HkP3ouJE_a1jzIL_JztpNMtkUOuelV7bz20mzVkVFyP_P4XW8Fm9uIVuivT_OQet1OyhlKv3ORuXVF6sD2fuYEv-Lcc3OVNtxy_80Nl2m4pZCowyf17QnbZhuWbgjmQJrcKfHHhq-yFohb7FGR8meHxgvB-InfU23PINupitFA_G0seuk9lvvXAFArqvkuAyOTP0wBzNHTl4HT4qkM2c2KeZGl8FQ4Jd_hkDMBuAmiNQ8XE7LS1kkwDOaS8hKuMkTps4fNb7gfWaIFa4FfBRm-ZWanVxU61zooxOmajfDPyAYG3_SVkfObSlMGopAiKM6Aly7o78xJGLdCl0Z2aCws3z1k_VZpdv9bmwGzWJpysldcTwyBLyoDfAQP8y7Plxe09bmfus-JkDrWGU",
"refresh_token": "def502003c32f3cdcb5fc33a27235d9effc81318233071fa0be74c69d0ec8bb4e649183d34eb993cd36a6c93c45ea91e47ce835dad785ac595723cbcbd069a86338e80289fc16d8732f26da9db915e7f8fd8f7da5983e426e8180c908ef2e85c7c313c94ebc8f90830362a1fae39bd0c7fa95efd989c85751cabbe5270c8f608ca7f446c51a8c39a6c9ff5600cef8a7417f8c9a3b34b3c25ff7c46160b7e4530f067f0365b451fb0dec42adc40cae3336b7e4028bd8df48f12f5de0444963ab05099dd15394f24d0986f894ea66e7755f7e29c92c18fe70ab0134673a8dae8ecaa6d05becf529ff281359b487eedef0686646057e84971eb83347c90b7f402010ae662aec7482c750627bac790971db12382e3d55851a454407db608d23707eb23a50bdfab5e8e273a0e67d446ed667c4a12fddc5082a1557eb3bef2353f8a152e5804ab919772529e2f455fb8a1821b53726d6b7b24aaf2d14f72648f3d698810f24557c3"
}
3. 多字段登录
待完善。。。
4. 使用token
当调用 Passport 保护下的路由时,接入的 API 应用需要将访问令牌作为 Bearer
令牌放在请求头 Authorization
中,如下:
$response = $client->request('GET', '/api/user', [
'headers' => [
'Accept' => 'application/json',
'Authorization' => 'Bearer '.$accessToken,
],
]);