Passport 验证 Token 方法和持续刷新过期时间问题

项目介绍

最近在做一个后台项目,目标是登录后无操作30分钟后自动过期,一直操作的情况下,过期时间一直刷新(目前不考虑每次操作修改对数据库的压力)

  • token有效期检测
  • 操作后自动刷新过期时间
  • 管理员手动登出其他登录用户
  • 单用户登录,二次登录作废上次登录token

token有效期检测

passport自带就有检测过期时间,这个用过都了解\
文件在League\OAuth2\Server\AuthorizationValidators\BearerTokenValidator

public function validateAuthorization(ServerRequestInterface $request)
    {
        .
        .
        .
        try {
            // Attempt to parse and validate the JWT
            // 这里会根据token解析出过期时间
            /**
            * 内容为这个
            * "exp" => Lcobucci\JWT\Claim\GreaterOrEqualsTo^ {#2944
            *     -name: "exp"
            *     -value: 1606462560
            *  }
            **/
            $token = (new Parser())->parse($jwt);
            .
            .
            .
            // Ensure access token hasn't expired
            $data = new ValidationData();
            $data->setCurrentTime(time());
            // 这里验证token是否有效
            if ($token->validate($data) === false) {
                throw OAuthServerException::accessDenied('Access token is invalid');
            }

            // Check if token has been revoked
            // 这样验证数据库中token是否已经被撤销,会进行一次查询
            // 最后验证结束还是查询一次,把查询内容放到auth('api')->user()->token()中
            if ($this->accessTokenRepository->isAccessTokenRevoked($token->getClaim('jti'))) {
                throw OAuthServerException::accessDenied('Access token has been revoked');
            }
            .
            .
            .
    }

有效期可以参考Passport OAuth 认证

操作后自动刷新过期时间

这个是目前遇到的问题,在数据库中可以看到oauth_access_tokens中,有 expires_at 字段,理所当然的,请求之后,修改这个过期时间

// $this->loginUser为自定义的,相当于$request->user('api')
$this->loginUser->token()->expires_at = Carbon::now()->addMinutes(30);
$this->loginUser->token()->save();

实际上用该token请求还是没有问题,百思不得其解后,找到问题所在

 // Ensure access token hasn't expired
$data = new ValidationData();
$data->setCurrentTime(time());
// 这里验证token是否有效
if ($token->validate($data) === false) {
    throw OAuthServerException::accessDenied('Access token is invalid');
}

这里只验证了token中存储的过期时间


if ($this->accessTokenRepository->isAccessTokenRevoked($token->getClaim('jti'))) {
    throw OAuthServerException::accessDenied('Access token has been revoked');
}

这里只验证了是否撤销(数据库 revoked 字段)


也就是说根本没有验证数据库的过期字段,再怎么修改过期时间也是无效的(因为只做存储查看作用,没实际验证)\
passport目前想要自己刷新过期时间,又不改变token的情况下,只能进行自定义一个中间件来解决了\
通过 $this->loginUser->token()->expires_at 来获取过期时间,然后自定义处理逻辑

管理员手动登出其他登录用户

这个就比较简单了

DB::table('oauth_access_tokens')->where('user_id', $user->id)
->update([
    'revoked' => 1
]);

直接作废该用户的所有 token 就完成了

单用户登录,二次登录作废上次登录token

这个和上面同理,通过 $this->loginUser->token()->getQueueableId() 获取当前登录用户数据库中对应的id

DB::table('oauth_access_tokens')->where('user_id', $this->loginUser->id)
            ->where('id', '!=', $this->loginUser->token()->getQueueableId())
            ->update([
                'revoked' => 1
            ]);

直接作废该用户的其他 token 就完成了

目前只能想到通过自定义中间件来处理刷新token有效时间来解决,如果有什么比较好的办法,欢迎讲解!

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!