[JWT]校验用户身份信息失败,但依然能获取token的值,求解

1. 问题描述?

我在A服务器与B服务器上分别部署了一模一样的Laravel9项目代码,使用nginx做负载均衡,将接口请求轮流转发到两台服务器上,客户端访问网站域名后会先到达master服务器,然后由master服务器轮流转发请求到A与B服务器上处理PHP的逻辑

A与B的Linux版本号,PHP版本,nginx版本都是一模一样的,PHP代码文件里,.env文件中的JWT的秘钥、加密方式、有效时间都是一模一样的

现在的问题是
当我请求登录时,master服务器将登录请求转发给A服务器,生成一个JWT的token返回给客户,客户带着这个token做后续请求时,master服务器将后续请求转发给B服务器,在B服务器上第一次验证用户身份时是验证不通过的,但是可以拿到token的值

也就是 auth(‘user’)->check()的结果是false
但是auth(‘user’)->getToken()的结果是有值的

但是当再次发起请求时无论是A处理还是B处理都是可以成功校验用户token和身份信息的,只有在另一台服务器第一次校验token时会校验失败

但是两台服务器的各个配置版本,JWT版本、秘钥、加密方式都是一模一样的

一开始以为nginx转发的时候没有把request Headers里面的Authorization带过去,但后来发现不是这个问题(因为在校验不成功的时候我使用PHP把token打印出来了,说明拿到token了但是check校验不成功),各位大佬有什么思路可以支支招吗?

2. 运行环境

1). 当前使用的 Laravel 版本?

Laravel 9.18.0

2). 当前使用的 php/php-fpm 版本?

PHP 版本:8.0.22(两台服务器都是这个版本)

php-fpm 版本:8.0.22

3). 当前系统

centos7.6(两台服务器上都是这个版本)

4). 业务环境

JWT版本:”tymon/jwt-auth”: “1.0.x-dev”

#JWT的生效时间(分钟)
JWT_TTL=720(两台服务器都是一模一样的)

#JWT的秘钥
JWT_SECRET=暂时保密(两台服务器都是一模一样的)

#JWT的算法
JWT_ALGO=HS256(两台服务器都是一模一样的)

5). 相关软件版本

3. 您期望得到的结果?

4. 您实际得到的结果?

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 25

check为false时,分析抛出的具体异常了吗

1年前 评论
Dark_Pony (楼主) 1年前
php_yt (作者) 1年前
Dark_Pony (楼主) 1年前

而且我自己用APIPOST工具,把token带到header里面,按照Authorization => Bearer token,调用接口每一次都能验证通过,只有走客户端vue项目接口时会出现这个问题,真是奇怪

1年前 评论
deatil 1年前
Dark_Pony (作者) (楼主) 1年前
deatil 1年前
Dark_Pony (作者) (楼主) 1年前
deatil 1年前
deatil 1年前
Dark_Pony (作者) (楼主) 1年前
deatil 1年前
deatil 1年前
Dark_Pony (作者) (楼主) 1年前
public function handle(Request $request, Closure $next)
{
    try {
        if ( auth('user')->parseToken()->authenticate() ) {
            return $next($request);
        }else {
            echo auth('user')->getToken();
            exit;
        }
    }catch(\Exception $e){
        \Log::info($e->getMessage());
    }
}

[2022-09-07 17:17:04] local.INFO: Method [authenticate] does not exist.
[2022-09-07 17:17:24] local.INFO: Method [authenticate] does not exist.

1年前 评论
Dark_Pony (作者) (楼主) 1年前
php_yt 1年前

楼主看一下两台服务器的时间是不是一致,jwt生成token时会包含一个token生成时间和一个可刷新时间,如果两台服务器的系统时间不一致,那么A服务器生成的token在B服务器可能会被校验失效,但是可刷新时间并未失效,因此可以获得新的token,可以在两台服务器同时生成两个token拿出来解析下具体内容有什么差异。

1年前 评论
Dark_Pony (楼主) 1年前
lgbxhr (作者) 1年前
Dark_Pony (楼主) 1年前
lgbxhr (作者) 1年前

我们现在在nginx的负载均衡里使用ip_hash的方式,确保同一个IP只会走同一台服务器,这样就避免了A服务器生成token,B服务器第一次校验失败的问题

1年前 评论

各位问题已经找到了,是由于每台Linux服务器的时间相差几秒钟导致的,要同步系统时间才能避免这个问题!

1年前 评论

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