[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(两台服务器都是一模一样的)
check为false时,分析抛出的具体异常了吗
而且我自己用APIPOST工具,把token带到header里面,按照Authorization => Bearer token,调用接口每一次都能验证通过,只有走客户端vue项目接口时会出现这个问题,真是奇怪
[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.
楼主看一下两台服务器的时间是不是一致,jwt生成token时会包含一个token生成时间和一个可刷新时间,如果两台服务器的系统时间不一致,那么A服务器生成的token在B服务器可能会被校验失效,但是可刷新时间并未失效,因此可以获得新的token,可以在两台服务器同时生成两个token拿出来解析下具体内容有什么差异。
我们现在在nginx的负载均衡里使用ip_hash的方式,确保同一个IP只会走同一台服务器,这样就避免了A服务器生成token,B服务器第一次校验失败的问题
各位问题已经找到了,是由于每台Linux服务器的时间相差几秒钟导致的,要同步系统时间才能避免这个问题!