Tips: tymon/jwt-auth 作者已通过增加 prv 字段修复这一问题#1167,但是如果你是用 dingo api + jwt 的话,该问题依然存在。#

JWT 多表验证隔离

为什么要做隔离

当同一个 laravel 项目有多端(移动端、管理端......)都需要使用 jwt 做用户验证时,如果用户表有多个(一般都会有),就需要做 token 隔离,不然会发生移动端的 token 也能请求管理端的问题,造成用户越权。

会引发这个问题的原因是 laravel 的 jwt token 默认只会存储数据表的主键的值,并没有区分是那个表的。所以只要 token 里携带的 ID 在你的用户表中都存在,就会导致越权验证。

我们来看看 laravel 的 jwt token 的原貌:

{
 "iss": "http://your-request-url",
 "iat": 1558668215,
 "exp": 1645068215,
 "nbf": 1558668215,
 "jti": "XakIDuG7K0jeWGDi",
 "sub": 1
}

携带数据的是 sub 字段,其他字段是 jwt 的验证字段。

我们只看到 sub 的值为 1,并没有说明是那个表或是哪个验证器的。这个 token 通过你的验证中间件时,你使用不同的 guard 就能拿到对应表 id 为 1 的用户(了解 guard 请查看 laravel 的文档)。

解决办法

想要解决用户越权的问题,我们只要在 token 上带上我们的自定义字段,用来区分是哪个表或哪个验证器生成的,然后再编写自己的中间件验证我们的自定义字段是否符合我们的预期。

添加自定义信息到 token

我们知道要使用 jwt 验证,用户模型必须要实现 JWTSubject 的接口(代码取自jwt 文档):

<"htmlcode">
/**
 * 额外在 JWT 载荷中增加的自定义内容
 *
 * @return array
 */
public function getJWTCustomClaims()
{
 return ['role' => 'admin'];
}

移动端用户模型:

/**
 * 额外在 JWT 载荷中增加的自定义内容
 *
 * @return array
 */
public function getJWTCustomClaims()
{
 return ['role' => 'user'];
}

这里添加了一个角色名作为用户标识。

这样管理员生成的 token 会像这样:

{
 "iss": "http://your-request-url",
 "iat": 1558668215,
 "exp": 1645068215,
 "nbf": 1558668215,
 "jti": "XakIDuG7K0jeWGDi",
 "sub": 1,
 "role": "admin"
}

移动端用户生成的 token 会像这样:

{
 "iss": "http://your-request-url",
 "iat": 1558668215,
 "exp": 1645068215,
 "nbf": 1558668215,
 "jti": "XakIDuG7K0jeWGDi",
 "sub": 1,
 "role": "user"
}

我们可以看到这里多了一个我们自己加的 role 字段,并且对应我们的用户模型。

接下来我们自己写一个中间件,解析 token 后判断是否是我们想要的角色,对应就通过,不对应就报 401 就好了。

编写 jwt 角色校验中间件

这里提供一个可全局使用的中间件 (推荐用在用户验证中间件前):

<"color: #ff0000">注册 jwt 角色校验中间件

在 app/Http/Kernel.php 中注册中间件:

 /**
  * The application's route middleware.
  *
  * These middleware may be assigned to groups or used individually.
  *
  * @var array
  */
 protected $routeMiddleware = [
  // ...省略 ...

  // 多表jwt验证校验
  'jwt.role' => \App\Http\Middleware\JWTRoleAuth::class,
 ];

使用 jwt 角色校验中间件

接下来在需要用户验证的路由组中添加我们的中间件:

Route::group([
 'middleware' => ['jwt.role:admin', 'jwt.auth'],
], function ($router) {
 // 管理员验证路由
 // ...
});

Route::group([
 'middleware' => ['jwt.role:user', 'jwt.auth'],
], function ($router) {
 // 移动端用户验证路由
 // ...
});

至此完成 jwt 多表用户验证隔离。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

华山资源网 Design By www.eoogi.com
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
华山资源网 Design By www.eoogi.com

《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线

暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。

艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。

《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。