场景
- 同事那里接手了一个lumen5.5项目,鉴权做的一塌糊涂; 所以需要重构一下这一块;选用的解决方案是dusterio/lumen-passport
package 简介
dusterio/lumen-passport
Making Laravel Passport work with Lumen
A simple service provider that makes Laravel Passport work with Lumen安装使用是很简单的, 但是这个牺牲了部分特性; 因为laravel-passport是基于web session的; 而lumen在5.2的时候已经废弃了session;
另外提一下这个package的readme.md是完全建立在读者对laravel-passport熟悉的基础上的; 文档极其简陋;需要对照
laravel-passport
安装
- 安装
- composer require dusterio/lumen-passport
- 配置
注册bootstrap/app.php
// Enable Facades
$app->withFacades();
// Enable Eloquent
$app->withEloquent();
// Enable auth middleware (shipped with Lumen)
$app->routeMiddleware([
‘auth’ => App\Http\Middleware\Authenticate::class,
]);
// Finally register two service providers - original one and Lumen adapter
$app->register(Laravel\Passport\PassportServiceProvider::class);
$app->register(Dusterio\LumenPassport\PassportServiceProvider::class);注册oauth表
Create new tables for Passport
php artisan migrate
Install encryption keys and other necessary stuff for Passport
php artisan passport:install配置config/auth.php
return [
‘defaults’ => [
‘guard’ => ‘api’,
‘passwords’ => ‘users’,
],
‘guards’ => [
‘api’ => [
‘driver’ => ‘passport’,
‘provider’ => ‘users’,
],
],
‘providers’ => [
‘users’ => [
‘driver’ => ‘eloquent’,
‘model’ => \App\User::class
]
]
];
鉴权
鉴权 (password grant)
- 请求方式
- POST /oauth/token
- 请求参数
字段 | 是否必须 | 类型 | 描述 |
---|---|---|---|
grant_type | Y | string | 目前只支持password |
client_id | Y | integer | client ID |
client_secret | Y | string | client secret |
username | Y | string | product key, product表的product_key |
password | Y | string | password 默认nicework |
scope | N | string | 所有的权限的时候 * |
- 分析
所以重点是怎么获取username, password? 因为鉴权Model 很多时候不是User; 或者没有username, password字段
- 解决
- User Model 添加 protected $table = ‘product’; 切换table
- findForPassport 方法执行username 指向的唯一字符串
- 认证密码字段,可以使用函数 getAuthPassword 指定; (这个函数返回选中model的字段值; 下图就是表示使用table中的 user_passwrod字段来做为密码 )
/**
* 自定义关键字查询方式
* @param $username
* @return mixed
*/
public function findForPassport($username)
{
return (new static())->where($this->password_search_key, $username)->first();
}
/**
* 设置用来认证的密码字段
* @return string
*/
public function getAuthPassword() : string
{
return $this->user_password;
}
refresh token api
- 请求方式
POST/oauth/token/refresh
- 分析
- 这里有bug
源码中可以看到: 使用到了$request->session()->token()但是session 已经废弃了
另外找时间研究一下; 好忙!
- 这里有bug
/**
* Get a fresh transient token cookie for the authenticated user.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function refresh(Request $request)
{
return (new Response('Refreshed.'))->withCookie($this->cookieFactory->make(
$request->user()->getKey(), $request->session()->token()
));
}