Passport OAuth 认证 | 官方扩展包 |《Laravel 5.8 中文文档 5.8》| Laravel China 社区


本站和网页 https://learnku.com/docs/laravel/5.8/passport/3907 的作者无关,不对其内容负责。快照谨为网络故障时之索引,不代表被搜索网站的即时页面。

Passport OAuth 认证 | 官方扩展包 |《Laravel 5.8 中文文档 5.8》| Laravel China 社区
Laravel
话题列表
社区 Wiki
优质外文
招聘求职
Laravel 实战教程
社区文档
登录
注册
Laravel 5.8 中文文档
展开或关闭
前言
发行说明
升级说明
贡献导引
入门指南
安装
配置信息
文件夹结构
Homestead
Valet
部署
核心架构
请求周期
服务容器
服务提供者
Facades
Contracts
基础功能
路由
中间件
CSRF 保护
控制器
请求
响应
视图
URL
Session
表单验证
错误
日志
前端开发
Blade 模板
本地化
前端指南
编译资源 Mix
安全相关
用户认证
API 认证
用户授权
Email 认证
加密解密
哈希
重置密码
综合话题
Artisan 命令行
广播系统
缓存系统
集合
事件系统
文件存储
辅助函数
邮件发送
消息通知
扩展包开发
队列
任务调度
数据库
快速入门
查询构造器
分页
数据库迁移
数据填充
Redis
Eloquent ORM
快速入门
模型关联
Eloquent 集合
修改器
API 资源
序列化
测试相关
快速入门
HTTP 测试
命令行测试
数据库测试
测试模拟器 Mocking
官方扩展包
Cashier 交易工具包
浏览器测试 Dusk
Envoy 部署工具
Horizon 队列管理工具
Passport OAuth 认证
Scout 全文搜索
Socialite 社会化登录
Telescope 应用调试工具
Laravel
首页
Laravel
Go
PHP
Vue.js
Python
Java
MySQL
Rust
LK
Elasticsearch
F2E 前端
Server
程序员
Database
DevTools
Computer Science
手机开发
AdonisJS
社区
Wiki
教程
Laravel 实战教程首页
《L01 Laravel 教程 - Web 开发实战入门》
《L02 Laravel 教程 - Web 开发实战进阶》
《L03 Laravel 教程 - 实战构架 API 服务器》
《L04 Laravel 教程 - 微信小程序从零到发布》
《L05 Laravel 教程 - 电商实战》
《L06 Laravel 教程 - 电商进阶》
《LX1 Laravel / PHP 扩展包视频教程》
《LX2 PHP 扩展包实战教程 - 从入门到发布》
《L07 Laravel 教程 - Laravel TDD 测试实战》
《LX3 Laravel 性能优化入门》
《LX4 Laravel / PHP 五分钟视频》
文档
社区文档首页
《Laravel 中文文档》
《Laravel 速查表》
《PHP 代码简洁之道》
《Laravel 编码技巧》
《Dcat Admin 中文文档》
《Laravel Nova 中文文档》
《Lumen 中文文档》
《Dingo API 中文文档》
《 Laravel 项目开发规范》
《构建 Laravel 开发环境》
登录
注册
微信登录
提交改进
Passport OAuth 认证
5.8
9.x
8.5
8.x
7.x
6.x
5.8
5.7
5.6
5.5
5.4
5.3
5.2
5.1
Laravel 5.8 中文文档
未匹配的标注
本文档最新版为 9.x,旧版本可能放弃维护,推荐阅读最新版!
Laravel Passport
介绍
安装
前端快速上手
部署 Passport
配置
令牌的使用期限
覆盖默认的模型
发放访问令牌
管理客户端
请求令牌
刷新令牌
密码授权令牌
创建密码授权客户端
请求密码授权令牌
请求所有作用域
自定义用户名字段
简化授权令牌
客户端授权令牌
个人访问令牌
创建个人访问令牌的客户端
管理个人访问令牌
路由保护
通过中间件
传递访问令牌
令牌作用域
定义作用域
默认作用域
给令牌分配作用域
检查作用域
使用 JavaScript 接入 API
事件
测试
介绍
在 Laravel 中,实现基于传统表单的登陆和授权已经非常简单,但是如何满足 API 场景下的授权需求呢?在 API 场景里通常通过令牌来实现用户授权,而非维护请求之间的 Session 状态。在 Laravel 项目中使用 Passport 可以轻而易举地实现 API 授权认证,Passport 可以在几分钟之内为你的应用程序提供完整的 OAuth2 服务端实现。Passport 是基于由 Andy Millington 和 Simon Hamp 维护的 League OAuth2 server 建立的。
注意:本文档假定你已熟悉 OAuth2 。如果你并不了解 OAuth2 ,阅读之前请先熟悉下 OAuth2 的 常用术语 和特性。
安装
在开始之前, 请通过 Composer 包管理器安装 Passport:
composer require laravel/passport
Passport 服务提供器使用框架注册自己的数据库迁移目录,因此在注册提供器后,就应该运行 Passport 的迁移命令来自动创建存储客户端和令牌的数据表:
php artisan migrate
接下来,运行 passport:install 命令来创建生成安全访问令牌时所需的加密密钥,同时,这条命令也会创建用于生成访问令牌的「个人访问」客户端和「密码授权」客户端:
php artisan passport:install
上面命令执行后,请将 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;
接下来,在 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',
];
/**
* 注册任何认证/授权服务。
* @return void
*/
public function boot()
$this->registerPolicies();
Passport::routes();
最后,将配置文件 config/auth.php 中授权看守器 guards 的 api 的 driver 选项改为 passport。此调整会让你的应用程序在在验证传入的 API 的请求时使用 Passport 的 TokenGuard 来处理:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
自定义迁移
如果你不打算使用 Passport 的默认迁移,你应该在 AppServiceProvider 的 register 方法中调用 Passport::ignoreMigrations 方法。 你可以用这个命令 php artisan vendor:publish --tag=passport-migrations 导出默认迁移。
默认情况下,Passport使用字段 「user_id」标识用户。如果想使用不同的字段标识用户(例如:uuid),可以修改默认的Passport迁移文件。
前端快速上手
注意:为了使用 Passport 的 Vue 组件,你必须使用 Vue JavaScript 框架。这些组件也使用了 Bootstrap CSS 框架。然而,如果你不打算使用这些工具,这些组件对于你自己的前端组件编写也十分有价值。
Passport 提供了一系列 JSON API ,你可以用它们来允许你的用户创建客户端和个人访问令牌。然而,编写与这些 API 交互的前端代码可能是很占用时间的。因此,Passport 也包括了预编译的 Vue 组件,你可以直接使用或将其作为你自己的前端参考。
要使用 Passport 的 Vue 组件,使用 vendor:publish Artisan 命令:
php artisan vendor:publish --tag=passport-components
被发布的组件将会被放到 resources/js/components 目录下。当组件被发布后,你应该在你的 resources/js/app.js 文件中注册它们:
Vue.component(
'passport-clients',
require('./components/passport/Clients.vue').default
);
Vue.component(
'passport-authorized-clients',
require('./components/passport/AuthorizedClients.vue').default
);
Vue.component(
'passport-personal-access-tokens',
require('./components/passport/PersonalAccessTokens.vue').default
);
注意:在Laravel v5.7.19之前,在注册组件时添加“.default”会导致控制台错误。有关此更改的解释,请参阅 Laravel Mix v4.0.0 发布说明.
在注册了组件后,请确保运行 npm run dev 来重新编译你的资源。 当你重编译你的资源后,你可以将组件放到你应用的模板中以开始创建客户端和个人访问令牌:
<passport-clients></passport-clients>
<passport-authorized-clients></passport-authorized-clients>
<passport-personal-access-tokens></passport-personal-access-tokens>
部署 Passport
第一次在你的生产环境部署 Passport 时,你大概需要运行 passport:keys 命令。这个命令生成 Passport 生成访问令牌所需的密钥。生成的密钥一般情况下不应放在版本控制中:
php artisan passport:keys
可以使用 Passport::loadKeysFrom 方法来自定义 Passport 密钥的加载路径:
/**
* 注册认证 / 授权服务
* @return void
*/
public function boot()
$this->registerPolicies();
Passport::routes();
Passport::loadKeysFrom('/secret-keys/oauth');
配置
令牌的有效期
默认情况下,Passport 发放的访问令牌是有一年有效期的。但是如果你想自定义访问令牌的有效期,可以使用 tokensExpireIn 和 refreshTokensExpireIn 方法。上述两个方法同样需要在 AuthServiceProvider 的 boot 方法中调用:
/**
* 注册认证 / 授权服务
* @return void
*/
public function boot()
$this->registerPolicies();
Passport::routes();
Passport::tokensExpireIn(now()->addDays(15));
Passport::refreshTokensExpireIn(now()->addDays(30));
覆盖默认模型
可以自由扩展 Passport 使用的模型,通过 Passport 类自定义模型覆盖默认模型:
use App\Models\Passport\Client;
use App\Models\Passport\AuthCode;
use App\Models\Passport\TokenModel;
use App\Models\Passport\PersonalAccessClient;
/**
* 注册认证 / 授权服务
* @return void
*/
public function boot()
$this->registerPolicies();
Passport::routes();
Passport::useClientModel(Client::class);
Passport::useTokenModel(TokenModel::class);
Passport::useAuthCodeModel(AuthCode::class);
Passport::usePersonalAccessClientModel(PersonalAccessClient::class);
发放访问令牌
熟悉 OAuth2 的开发者一定知道, OAuth2 中必不可少的部分就是授权码。当使用授权码时,客户端应用程序会将用户重定向到你的服务器,他们将批准或拒绝向客户端发出访问令牌的请求。
管理客户端
首先,构建需要与应用程序 API 交互的应用程序,开发人员将需要通过创建一个「客户端」来注册自己的应用程序。一般来说,这包括在用户批准其授权请求后,提供其应用程序的名称和应用程序可以重定向到的 URL。
The passport:client 命令
创建客户端最简单的方式是使用 Artisan 命令 passport:client,你可以使用此命令创建自己的客户端,用于测试你的 OAuth2 的功能。在你执行 client 命令时,Passport 会提示你输入有关客户端的信息,最终会给你提供客户端的 ID 和 密钥:
php artisan passport:client
Redirect URLs
当有多个重定向 URL 白名单时,可以在 passport:client 命令提示输入URL时,使用逗号分隔来指定:
http://example.com/callback,http://examplefoo.com/callback
注意:任何包含逗号的 URL 都必须进行编码。
JSON API
考虑到你的用户无法使用 client 命令,Passport 为此提供了可用于创建「客户端」的 JSON API。这样你就不用再花时间编写控制器来创建、更新和删除客户端。
然而,你仍旧需要基于 Passport 的 JSON API 开发一套前端界面,为你的用户提供管理客户端的面板。下面我们会列出所有用于管理客户端的 API,为了方便起见,我们使用 Axios 来演示对端口发出 HTTP 请求。
这个 JSON API 由 web 和 auth 两个中间件保护,所以只能从应用程序中调用,不能从外部调用。
Tip:如果你不想自己实现整个客户端管理的前端界面,可以使用 前端快速上手 在几分钟内组建一套功能齐全的前端界面。
GET /oauth/clients
此路由会返回认证用户的所有客户端。主要用途是列出所有用户的客户端,以便他们可以编辑或删除它们:
axios.get('/oauth/clients')
.then(response => {
console.log(response.data);
});
POST /oauth/clients
此路由用于创建新客户端。它需要两个参数:客户端的名称 name 和授权后回调的URL redirect。在批准或拒绝授权请求后,用户会被重定向到 redirect 参数提供的链接。
当客户端创建后,会返回客户端的 ID 和密钥。客户端可以使用这两个值从你的授权服务请求访问令牌 (Access token) 。该路由会返回新的客户端实例:
const data = {
name: 'Client Name',
redirect: 'http://example.com/callback'
};
axios.post('/oauth/clients', data)
.then(response => {
console.log(response.data);
})
.catch (response => {
// 在response里列出错误详情...
});
PUT /oauth/clients/{client-id}
此路由用于更新客户端信息。它需要两个参数:客户端的名称 name 和授权后回调的URL redirect。在批准或拒绝授权请求后,用户会被重定向 redirect 到这个链接。此路由会返回更新后的客户端实例:
const data = {
name: 'New Client Name',
redirect: 'http://example.com/callback'
};
axios.put('/oauth/clients/' + clientId, data)
.then(response => {
console.log(response.data);
})
.catch (response => {
// 在response里列出错误详情...
});
DELETE /oauth/clients/{client-id}
此路由用于删除客户端(client):
axios.delete('/oauth/clients/' + clientId)
.then(response => {
//
});
请求令牌
授权时的重定向
客户端创建之后,开发者会使用此客户端的 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);
});
Tip:注意,路由 /oauth/authorize 已经在 Passport::routes 方法中定义。你不需要手动定义此路由。
批准请求
接收到授权请求时,Passport 会自动向用户显示一个模版页面,允许用户批准或拒绝授权请求。如果用户批准请求,他们会被重定向回接入的应用程序指定的 redirect_uri。redirect_uri 必须和客户端创建时指定的 redirect 链接完全一致。
如果你想自定义授权确认页面,可以使用 Artisan 命令 vendor:publish 发布 Passport 的视图。发布后的视图文件存放在 resources/views/vendor/passport:
php artisan vendor:publish --tag=passport-views
将授权码转换为访问令牌
用户批准授权请求后,会被重定向回接入的应用程序。然后接入应用应该将通过 POST 请求向你的应用程序申请访问令牌。请求应该包括当用户批准授权请求时由应用程序发出的授权码。在下面的例子中,我们使用 Guzzle HTTP 库来实现这次 POST 请求:
Route::get('/callback', function (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);
});
路由 /oauth/token 返回的 JSON 响应中会包含 access_token 、refresh_token 和 expires_in 属性。expires_in 属性包含访问令牌的有效期(单位:秒)。
Tip:像 /oauth/authorize 路由一样,/oauth/token 路由在 Passport::routes 方法中定义了,你没必要手动去定义它。默认情况下,此路由使用“ThrottleRequests”中间件的设置进行限流。
刷新令牌
如果你的应用程序发放了短期的访问令牌,用户将需要通过在发出访问令牌时提供给他们的刷新令牌来刷新其访问令牌。在下面的例子中,我们使用 Guzzle HTTP 库来刷新令牌:
$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);
路由 /oauth/token 会返回一个 JSON 响应,其中包含 access_token 、refresh_token 和 expires_in 属性。expires_in 属性包含访问令牌的有效时间(单位:秒)。
密码授权令牌
OAuth2 密码授权机制可以让你自己的客户端(如移动应用程序)使用邮箱地址或者用户名和密码获取访问令牌。如此一来你就可以安全地向自己的客户端发出访问令牌,而不需要遍历整个 OAuth2 授权代码重定向流程
创建密码授权客户端
在应用程序通过密码授权机制来发布令牌之前,在 passport:client 命令后加上 --password 参数来创建密码授权的客户端。如果你已经运行了 passport:install 命令,则不需要再运行此命令:
php artisan passport:client --password
请求令牌
创建密码授权的客户端后,就可以使用用户的电子邮件地址和密码向 /oauth/token 路由发出 POST 请求来获取访问令牌。而该路由已经由 Passport::routes 方法注册,因此不需要手动定义它。如果请求成功,会在服务端返回的 JSON 响应中收到一个 access_token 和 refresh_token:
$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);
Tip:默认情况下,访问令牌是长期有效的。你可以根据需要 配置访问令牌的有效时间 。
请求所有作用域
使用密码授权机制时,可以通过请求 scope 参数 * 来授权应用程序支持的所有范围的令牌。如果你的请求中包含 scope 为 * 的参数,令牌实例上的 can 方法会始终返回 true。这种作用域的授权只能分配给使用 password 授权时发出的令牌:
$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' => '*',
],
]);
自定义用户名字段
当使用密码授权时,Passport默认使用 email 作为「用户名」。但是,你可以通过在模型上定义一个 findForPassport 方法来自定义用户名字段:
<?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;
/**
* 通过用户名找到对应的用户信息
* @param string $username
* @return \App\User
*/
public function findForPassport($username)
return $this->where('username', $username)->first();
隐式授权令牌
隐式授权类似于授权码授权,但是它只将令牌返回给客户端而不交换授权码。这种授权最常用于无法安全存储客户端凭据的 JavaScript 或移动应用程序。通过调用 AuthServiceProvider 中的 enableImplicitGrant 方法来启用这种授权:
/**
* 注册认证 / 授权服务
* @return void
*/
public function boot()
$this->registerPolicies();
Passport::routes();
Passport::enableImplicitGrant();
调用上面方法开启授权后,开发者可以使用他们的客户端 ID 从应用程序请求访问令牌。接入的应用程序应该向你的应用程序的 /oauth/authorize 路由发出重定向请求,如下所示:
Route::get('/redirect', function () {
$query = http_build_query([
'client_id' => 'client-id',
'redirect_uri' => 'http://example.com/callback',
'response_type' => 'token',
'scope' => '',
]);
return redirect('http://your-app.com/oauth/authorize?'.$query);
});
Tip:注意,/oauth/authorize 路由已经在 Passport::routes 方法中定义好,所以无需再次手动定义此路由。
客户端凭据授权令牌
客户端凭据授权适用于机器到机器的认证。例如,你可以在通过 API 执行维护任务中使用此授权。
在客户端凭据授权之前,需要先创建一个客户端凭据授权的客户端,你可以使用 passport:client 命令的 --client 参数来创建:
php artisan passport:client --client
接下来,要使用这种授权,你首先需要在 app/Http/Kernel.php 的 $routeMiddleware 变量中添加新的中间件:
use Laravel\Passport\Http\Middleware\CheckClientCredentials;
protected $routeMiddleware = [
'client' => CheckClientCredentials::class,
];
然后,在路由上追加这个中间件:
Route::get('/orders', function (Request $request) {
...
})->middleware('client');
若要将对路由的访问限制在某个作用域内,可在将 client 中间件附加到路由时提供以逗号分隔的所需作用域列表:
Route::get('/orders', function (Request $request) {
...
})->middleware('client:check-status,your-scope');
获取令牌
通过向 oauth/token 接口发出请求来获取令牌:
$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'];
个人访问令牌
有时候,用户要在不经过传统的授权码重定向流程的情况下向自己发出访问令牌。允许用户通过应用程序用户界面对自己发出令牌,有助于用户体验你的 API,或者也可以将其作为一种更简单的发布访问令牌的方式。
注意:个人访问令牌是永久有效的,就算使用了 tokensExpireIn 和 refreshTokensExpireIn 方法也不会修改它的生命周期。
创建个人访问客户端
在你的应用程序发布个人访问令牌之前,你需要在 passport:client 命令后带上 --personal 参数来创建对应的客户端。如果你已经运行了 passport:install 命令,则无需再运行此命令:
php artisan passport:client --personal
如果你已经创建了个人访问客户端,你可以通过调用 AuthServiceProvider 中的 personalAccessClientId 方法来启用:
/**
* 注册认证 / 授权服务
* @return void
*/
public function boot()
$this->registerPolicies();
Passport::routes();
Passport::personalAccessClientId('client-id');
管理个人访问令牌
创建个人访问客户端后,你可以使用 User 模型实例上的 createToken 方法来为给定用户发布令牌。createToken 方法接受令牌的名称作为其第一个参数和可选的 作用域 数组作为其第二个参数:
$user = App\User::find(1);
// 创建没有作用域的访问令牌...
$token = $user->createToken('Token Name')->accessToken;
// 创建有作用域的访问令牌...
$token = $user->createToken('My Token', ['place-orders'])->accessToken;
JSON API
Passport 中也有用来管理个人访问令牌的 JSON API,你可以将其与自己的前端配对,为用户提供管理个人访问令牌的仪表板。下面我们会介绍用于管理个人访问令牌的所有 API 接口。方便起见,我们使用 Axios 来演示对 API 的接口发出 HTTP 请求。
JSON API 由 web 和 auth 中间件保护;因此,只能从您自己的应用程序中调用它。无法从外部源调用它。
Tip:如果你不想实现自己的个人访问令牌管理的前端界面,可以根据 前端快速上手 在几分钟内组建功能齐全的前端界面。
GET /oauth/scopes
此路由会返回应用程序中定义的所有 作用域。你可以使用此路由列出用户可能分配给个人访问令牌的范围:
axios.get('/oauth/scopes')
.then(response => {
console.log(response.data);
});
GET /oauth/personal-access-tokens
此路由返回认证用户创建的所有个人访问令牌。这主要用于列出所有用户的令牌,以便他们可以编辑或删除它们:
axios.get('/oauth/personal-access-tokens')
.then(response => {
console.log(response.data);
});
POST /oauth/personal-access-tokens
此路由用于创建新的个人访问令牌。它需要两个数据:令牌的 name 和 scpoe:
const data = {
name: 'Token Name',
scopes: []
};
axios.post('/oauth/personal-access-tokens', data)
.then(response => {
console.log(response.data.accessToken);
})
.catch (response => {
// 列出响应中错误...
});
DELETE /oauth/personal-access-tokens/{token-id}
此路由可用于删除个人访问令牌:
axios.delete('/oauth/personal-access-tokens/' + tokenId);
路由保护
通过中间件
Passport 包含一个 验证保护机制 可以验证请求中传入的访问令牌。配置 api 的看守器使用 passport 驱动程序后,只需要在需要有效访问令牌的任何路由上指定 auth:api 中间件:
Route::get('/user', function () {
//
})->middleware('auth:api');
传递访问令牌
当调用 Passport 保护下的路由时,接入的 API 应用需要将访问令牌作为 Bearer 令牌放在请求头 Authorization 中。例如,使用 Guzzle HTTP 库时:
$response = $client->request('GET', '/api/user', [
'headers' => [
'Accept' => 'application/json',
'Authorization' => 'Bearer '.$accessToken,
],
]);
令牌作用域
作用域可以让 API 客户端在请求账户授权时请求特定的权限。例如,如果你正在构建电子商务应用程序,并不是所有接入的 API 应用都需要下订单的功能。你可以让接入的 API 应用只被允许授权访问订单发货状态。换句话说,作用域允许应用程序的用户限制第三方应用程序执行的操作。
定义作用域
你可以在 AuthServiceProvider 的 boot 方法中使用 Passport::tokensCan 方法来定义 API 的作用域。tokensCan 方法接受一个包含作用域名称和描述的数组作为参数。作用域描述将会在授权确认页中直接展示给用户,你可以将其定义为任何你需要的内容:
use Laravel\Passport\Passport;
Passport::tokensCan([
'place-orders' => 'Place orders',
'check-status' => 'Check order status',
]);
默认作用域
如果客户端没有请求任何特定的范围,你可以在 AuthServiceProvider 的 boot 方法中使用 Passport::setDefaultScope 方法来定义默认的作用域。
use Laravel\Passport\Passport;
Passport::setDefaultScope([
'check-status',
'place-orders',
]);
给令牌分配作用域
请求授权码
使用授权码请求访问令牌时,接入的应用需为 scope 参数指定所需作用域。 scope 参数包含多个作用域时,名称之间使用空格分割:
Route::get('/redirect', function () {
$query = http_build_query([
'client_id' => 'client-id',
'redirect_uri' => 'http://example.com/callback',
'response_type' => 'code',
'scope' => 'place-orders check-status',
]);
return redirect('http://your-app.com/oauth/authorize?'.$query);
});
分发个人访问令牌
使用 User 模型的 createToken 方法发放个人访问令牌时,可以将所需作用域的数组作为第二个参数传给此方法:
$token = $user->createToken('My Token', ['place-orders'])->accessToken;
检查作用域
Passport 包含两个中间件,可用于验证传入的请求是否包含访问指定作用域的令牌。 使用之前,需要将下面的中间件添加到 app/Http/Kernel.php 文件的 $routeMiddleware 属性中:
'scopes' => \Laravel\Passport\Http\Middleware\CheckScopes::class,
'scope' => \Laravel\Passport\Http\Middleware\CheckForAnyScope::class,
检查所有作用域
路由可以使用 scopes 中间件来检查当前请求是否拥有指定的 所有 作用域:
Route::get('/orders', function () {
// Access token has both "check-status" and "place-orders" scopes...
})->middleware('scopes:check-status,place-orders');
检查任意作用域
路由可以使用 scope 中间件来检查当前请求是否拥有指定的 任意 作用域:
Route::get('/orders', function () {
// 访问令牌具有 "check-status" 或 "place-orders" 作用域...
})->middleware('scope:check-status,place-orders');
检查令牌实例上的作用域
就算含有访问令牌验证的请求已经通过应用程序的验证,你仍然可以使用当前授权 User 实例上的 tokenCan 方法来验证令牌是否拥有指定的作用域:
use Illuminate\Http\Request;
Route::get('/orders', function (Request $request) {
if ($request->user()->tokenCan('place-orders')) {
//
});
附加作用域方法
scopeIds 方法将返回所有已定义 ID / 名称的数组:
Laravel\Passport\Passport::scopeIds();
scopes 方法将返回一个 包含所有已定义作用域数组的 Laravel\Passport\Scope 实例:
Laravel\Passport\Passport::scopes();
scopesFor 方法将返回与给定 ID / 名称匹配的 Laravel\Passport\Scope 实例数组:
Laravel\Passport\Passport::scopesFor(['place-orders', 'check-status']);
你可以使用hasScope方法确定是否已定义给定作用域:
Laravel\Passport\Passport::hasScope('place-orders');
使用 JavaScript 接入 API
在构建 API 时, 如果能通过 JavaScript 应用接入自己的 API 将会给开发过程带来极大的便利。这种 API 开发方法允许你使用自己的应用程序的 API 和别人共享的 API 。你的 Web 应用程序、移动应用程序、第三方应用程序以及可能在各种软件包管理器上发布的任何 SDK 都可能会使用相同的 API 。
通常,如果要在 JavaScript 应用程序中使用 API ,需要手动向应用程序发送访问令牌,并将其传递给应用程序。但是, Passport 有一个可以处理这个问题的中间件。将 CreateFreshApiToken 中间件添加到 app/Http/Kernel.php 文件中的 web 中间件组就可以了:
'web' => [
// 其他中间件...
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],
注意:你应该确保在您的中间件堆栈中 CreateFreshApiToken 中间件之前列出了 EncryptCookies 中间件。
这个 Passport 中间件将在你所有的对外请求中添加一个 laravel_token cookie 。该 cookie 将包含一个加密后的 JWT , Passport将用来验证来自 JavaScript 应用程序的 API 请求。至此,你可以在不明确传递访问令牌的情况下向应用程序的 API 发出请求:
axios.get('/api/user')
.then(response => {
console.log(response.data);
});
自定义 Cookie 名称
如果需要, 你可以在 AuthServiceProvider 的 boot 方法中使用 Passport::cookie 方法来自定义 laravel_token cookie 的名称。
/**
* 注册认证 / 授权服务
* @return void
*/
public function boot()
$this->registerPolicies();
Passport::routes();
Passport::cookie('custom_name');
CSRF 保护
当使用这种授权方法时,默认的 Laravel JavaScript 脚手架会让 Axios 发送 X-CSRF-TOKEN 和 X-Requested-With 请求头。另外,你必须确保 HTML meta 标签 标签 中包含了 CSRF 令牌:
// In your application layout...
<meta name="csrf-token" content="{{ csrf_token() }}">
// Laravel's JavaScript scaffolding...
window.axios.defaults.headers.common = {
'X-Requested-With': 'XMLHttpRequest',
};
事件
Passport 在发出访问令牌和刷新令牌时触发事件。你可以在应用程序 的 EventServiceProvider 中为这些事件追加监听器,并在监听器中撤销或修改其他令牌:
/**
* 应用程序事件监听映射
* @var array
*/
protected $listen = [
'Laravel\Passport\Events\AccessTokenCreated' => [
'App\Listeners\RevokeOldTokens',
],
'Laravel\Passport\Events\RefreshTokenCreated' => [
'App\Listeners\PruneOldTokens',
],
];
测试
Passport 的 actingAs 方法可以指定当前已认证用户及其作用域。actingAs 方法的第一个参数是用户实例,第二个参数是用户令牌作用域数组:
use App\User;
use Laravel\Passport\Passport;
public function testServerCreation()
Passport::actingAs(
factory(User::class)->create(),
['create-servers']
);
$response = $this->post('/api/create-server');
$response->assertStatus(201);
本文章首发在 LearnKu.com 网站上。
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
原文地址:https://learnku.com/docs/laravel/5.8/pas...
译文地址:https://learnku.com/docs/laravel/5.8/pas...
上一篇
下一篇
Markdown 文本
纠错改进
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
贡献者:3
推荐文章:
更多推荐...
博客
[扩展推荐] 使用 laravel-gridCaptcha 本地生成类似于谷歌点图验证码
22
1年前
翻译
Laravel 7 教程:使用 Passport 来构建 API 授权(大量代码)
15
2年前
博客
uniapp 小程序 Laravel+jwt 权限认证完整系列
38
11
2年前
翻译
Laravel 教程:使用 Laravel Sanctum 作为 API 认证来构建 Vue.js 应用
23
18
2年前
博客
Passport 多用户表登录 --个人令牌
10
2年前
博客
Laravel 用户认证 Auth
15
2年前
讨论数量: 18
发起讨论
只看当前版本
else
4年前
Laravel/passport 安装失败?
个点赞 | 5 个回复 |
问答
| 课程版本 5.5
Achais
3年前
由于我使用的是 Laradock A 站点请求 B 站点使用域名访问不到怎么办?
个点赞 | 2 个回复 |
问答
| 课程版本 5.5
雪风
4年前
cURL error 3: <url> malformed (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)
个点赞 | 5 个回复 |
分享
| 课程版本 5.7
QYlaravel
4年前
RevokeOldTokens 事件无法触发?
个点赞 | 5 个回复 |
问答
| 课程版本 5.6
zhizubaba
4年前
Passport OAuth 的安全疑问?
个点赞 | 3 个回复 |
问答
| 课程版本 5.6
Age_Chen
2年前
passport使用auth:api中间件登录验证,已经获取到token了,但是报Unauthenticated错误。
个点赞 | 5 个回复 |
问答
| 课程版本 5.8
Nevermore8579
3年前
安装时执行第二步 PHP artisan migrate 为什么只生成了 1 张 user 表?
个点赞 | 5 个回复 |
问答
| 课程版本 5.8
蒙挚
8个月前
[急急]关于 Passport OAuth 认证的问题
个点赞 | 3 个回复 |
问答
| 课程版本 9.x
Achais
3年前
passport 退出你们怎么操作的?1 是再刷新一次 2 是注销 我不清楚注销代码怎么写 有大神知道的么?
个点赞 | 3 个回复 |
问答
| 课程版本 5.5
qiyeal
2年前
passport oauth账号密码登录报错
个点赞 | 2 个回复 |
问答
| 课程版本 5.5
一个人的江湖
3年前
无法执行 PHP artisan migrate 进行迁移
个点赞 | 2 个回复 |
问答
| 课程版本 5.6
Liuzhipeng_laravel
3年前
Passport 会自动向用户显示一个模版页面,允许用户批准或拒绝授权请求。Route [login] not defined.
个点赞 | 2 个回复 |
问答
| 课程版本 5.6
传说中的五毛
3年前
使用 JavaScript 接入 API axios 访问 API 路由时候 401 错误
个点赞 | 1 个回复 |
问答
| 课程版本 5.5
王鲸弋
4年前
访问令牌的加密密钥 忘记了怎么找回呢?
个点赞 | 1 个回复 |
问答
| 课程版本 5.5
noecs
4年前
Laravel5.5 Passport 中的检查令牌作用域使用场景是什么
个点赞 | 1 个回复 |
问答
| 课程版本 5.5
feimn
2年前
解决 使用 Composer 安装 passport 包的报错
个点赞 | 0 个回复 |
分享
| 课程版本 5.5
hello-laravel
3年前
OAuth 2.0 隐式模式和简化模式是一个东西吗?
个点赞 | 0 个回复 |
问答
| 课程版本 5.7
努力的Charlie
4年前
resources/assets/JS/components 5.7 assets 不存在
个点赞 | 0 个回复 |
问答
| 课程版本 5.7
社区赞助商
成为赞助商
关于 LearnKu
LearnKu 是终身编程者的修道场
做最专业、严肃的技术论坛
LearnKu 诞生的故事
资源推荐
《社区使用指南》
《文档撰写指南》
《LearnKu 社区规范》
《提问的智慧》
服务提供商
其他信息
成为版主
所有测验
联系站长(反馈建议)
粤ICP备18099781号-6
粤公网安备 44030502004330号
违法和不良信息举报
由 Summer 设计和编码 ❤
请登录
提交
忘记密码?
or
注册
第三方账号登录
微信登录
GitHub 登录
内容举报
匿名举报,为防止滥用,仅管理员可见举报者。
我要举报该,理由是:
垃圾广告:恶意灌水、广告、推广等内容
无意义内容:测试、灌水、文不对题、消极内容、文章品质太差等
违规内容:色情、暴利、血腥、敏感信息等
不友善内容:人身攻击、挑衅辱骂、恶意行为
科学上网:翻墙、VPN、Shadowsocks,政策风险,会被关站!
不懂提问:提问太随意,需要再做一遍《提问的智慧》测验
随意提问:提问没有发布在社区问答分类下
排版混乱:没有合理使用 Markdown 编写文章,未使用代码高亮
内容结构混乱:逻辑不清晰,内容混乱,难以阅读
标题随意:标题党、标题不释义
尊重版权:分享付费课程、破解软件(付费),侵犯作者劳动成果
其他理由:请补充说明
举报
取消