通过 Passport 实现 API 请求认证(移动端的密码授权令牌)
前言
大家好,新年快乐。这篇主要讲通过 Passport 实现 API 请求认证,选择 Passport 的理由主要是官方推荐以及好像 Dingo API 不太支持Laravel6.0版本,接下来就常用的两个需求介绍 Passport 的使用。
安装并初始化
- 首先通过 Composer 安装 Passport 扩展包:
composer require laravel/passport
- 运行数据库迁移命令创建 OAuth 相关数据表
php artisan migrate
- 接着运行下列命令
php artisan passport:install
- 在对应模型类中使用 Laravel\Passport\HasApiTokens Trait,比如 User 模型:
... use Laravel\Passport\HasApiTokens; class User extends Authenticatable { use HasApiTokens, Notifiable; ...
- 在 AuthServiceProvider 的 boot 方法中注册 API 认证相关路由:
// 引入命名空间 use Laravel\Passport\Passport; ... public function boot() { ... //注册 API 认证路由 Passport::routes(); }
- 修改配置文件 config/auth.php,将 API 认证驱动由 token 修改为 passport:
'guards' => [ ... 'api' => [ 'driver' => 'passport',//这里 'provider' => 'users', ], ],
获取密码授权令牌
创建客户端
php artisan passport:client --password
我们会得到类似下面的内容:
Client_ID:3 Client_Secret:2JPrCvRyoJ14f0OqCe6nnQZNDfPLNNPY7TcfDnco
将敏感信息放进.env文件
CLIENT_ID=3 CLIENT_SECRET=2JPrCvRyoJ14f0OqCe6nnQZNDfPLNNPY7TcfDnco
在 config/services.php 中添加配置项:
'blog' => [ 'appid' => env('CLIENT_ID'), 'secret' => env('CLIENT_SECRET'), ]
在相应的控制器中写入登录验证并返回token值的方法:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use GuzzleHttp\Client; class IndexController extends Controller { public function login(Request $request) { $http = new Client(); // 发送相关字段到后端应用获取授权令牌,网址为我的测试网址 $response = $http->post('http://test.test/oauth/token', [ 'form_params' => [ 'grant_type' => 'password', 'client_id' => config('services.blog.appid'), 'client_secret' => config('services.blog.secret'), 'username' => $request->input('email'), // 这里传递的是邮箱 'password' => $request->input('password'), // 传递密码信息 'scope' => '*' ], ]); return response($response->getBody()); } }
这样当用户访问这个方法并传入正确的登录邮箱及密码的时候就能返回相应的token值,示例如下图:
其中access_token就是我们想要的token了。
刷新令牌
如何刷新令牌?通常情况下,我习惯将置换令牌与刷新令牌放在一起,所以重新封装login方法:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use GuzzleHttp\Client;
class IndexController extends Controller
{
public function login(Request $request)
{
$http = new Client();
//判断grant_type类型
if($request->input('type')=="refresh_token"){
$response = $http->post('http://blog.test/oauth/token', [
'form_params' => [
'grant_type' => 'refresh_token',
'refresh_token' => $request->input('token'),
'client_id' => config('services.blog.appid'),
'client_secret' => config('services.blog.secret'),
'scope' => '*',
],
]);
}else{
// 发送相关字段到后端应用获取授权令牌,网址为我的测试网址
$response = $http->post('http://test.test/oauth/token', [
'form_params' => [
'grant_type' => 'password',
'client_id' => config('services.blog.appid'),
'client_secret' => config('services.blog.secret'),
'username' => $request->input('email'), // 这里传递的是邮箱
'password' => $request->input('password'), // 传递密码信息
'scope' => '*'
],
]);
}
return response($response->getBody());
}
}
参数问题:当置换令牌时需要type、email、password,当刷新令牌时需要type、access_token值。
当然这只是一种方案,仅供参考
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: