使用JWT认证的时候,一旦JWT_REFRESH_TTL到期,那么也是会自动退出的影响用户体验

class AuthorizationsController extends Controller
{
    public function store(AuthorizationRequest $request)
    {
        $credentials = [
            'phone' => $request->phone,
            'password' => $request->password
        ];

        if (!$token = \Auth::guard('api')->attempt($credentials)) {
            throw new AuthenticationException('用户名或密码错误');
        }

        return $this->respondWithToken($token)->setStatusCode(201);
    }

    protected function respondWithToken($token)
    {
        return response()->json([
            'access_token' => $token,
            'token_type' => 'Bearer',
            'expires_in' => auth('api')->factory()->getTTL() * 60
        ]);
    }

    public function update()
    {
        $token = auth('api')->refresh();
        return $this->respondWithToken($token);
    }

    public function destroy()
    {
        auth('api')->logout();
        return response(null, 204);
    }
}

使用的软件包是tymon/jwt-auth
不过就算把JWT_REFRESH_TTL设置的比较久,仍然会存在用户在某一天操作的时候突然被T出来,这个你们是怎么解决的
假如说JWT_REFRESH_TTL设置为1天,然后你现在下午1点钟登录,明天12点半操作,半个小时后还是仍然会突然退出,时间设置久了也是一样会存在这样的问题,只是频率小而已

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 19

access_token 都没了 那代码肯定也没了,数据库地址也泄露了。还管什么jwt安全不安全。

8个月前 评论
sanders

一把锁不够?那就再上一把锁! :stuck_out_tongue_closed_eyes:

8个月前 评论
深蓝色 (楼主) 8个月前
sanders (作者) 8个月前
深蓝色 (楼主) 8个月前
sanders (作者) 8个月前

jwt本来就不是安全的,所以会有过期设置。难道你觉得cookie就很安全吗?

8个月前 评论

JWT_REFRESH_TTL 设置时间就是为了把你 T 出去啊

你简直问的莫名奇妙...你不想踢出活跃用户就维护一下过期时间呗

8个月前 评论

或许可以考虑记录客户端 ip ,异地登录和多台设备登录需要短信验证码 ?

8个月前 评论

问题1:

这就是 JWT 本身的特性,我很讨厌这种问问题的方式,你所谓的 「access_token 丢失」你要描述具体的业务情况,是怎么丢的?黑客是怎么进来的?如果按照你这种假设,那没有一种系统是安全的,你还可以假设「黑客获取到你服务器的 root 密码」

问题2:

有个解决方案叫 「JWT 无痛刷新」了解一下,大概的解决方案是后端创建一个中间件,在前端发送 Token 过来时去做个验证,如果快要到期了,直接返回一个新的 Token 到 Response Header。

然后前端在全局中做判断,如果 Response Header 中包含 New-Token,直接替换本地 Token,达到无感知刷新 Token

这都是好多年前的话题了。

8个月前 评论
徵羽宫 8个月前
MArtian (作者) 8个月前
徵羽宫 8个月前
GeorgeKing 8个月前
MArtian (作者) 8个月前

可以看下这个
这个是 当发现token过期后会重新在 response headers(返回的headers参数中) 携带一个 token 将此token替换原来的token 用户就可以做到无感的处理
当然 这个是建立在 token 过期但是 没有刷新时间的处理 如果过了刷新的时间 则只能用户重新登录处理

public function handle(Request $request, Closure $next, $guard_name = 'api_admin')
    {
        // 检查此次请求中是否带有 token,如果没有则抛出异常。
        $this->checkForToken($request);
        try {
            // 设置工厂应提供的默认保护驱动程序。
            Auth::shouldUse($guard_name);
            // 检测用户是否已经登录, 同时判断当前用户的分组是否一致
            if ($user = $this->auth->parseToken()->authenticate()) {
                return $next($request);
            }
            throw new UnauthorizedHttpException('jwt-auth', '未登录');
        } catch (TokenExpiredException  $exception) {
            try {
                // 刷新用户的 token
                $token = $this->auth->refresh();
                // 使用一次性登录以保证此次请求的成功
                Auth::guard($guard_name)
                    ->onceUsingId(
                        $this->auth->manager()
                            ->getPayloadFactory()
                            ->buildClaimsCollection()
                            ->toPlainArray()['sub']
                    );
            } catch (JWTException $exception) {
                // 如果捕获到此异常,即代表 refresh 也过期了,用户无法刷新令牌,需要重新登录。
                throw new UnauthorizedHttpException('jwt-auth', $exception->getMessage());
            }
        } catch (JWTException $exception) {
            throw new UnauthorizedHttpException('jwt-auth', $exception->getMessage());
        }
        // 设置请求头header 避免获取用户时出现问题
        $request->headers->set('Authorization', 'Bearer '.$token);
        return $this->setAuthenticationHeader($next($request), $token);
    }
8个月前 评论

我最终决定,用永久有效的Token,针对安全性有要求的,加入中间件,验证一下短信验证码

8个月前 评论

上策: 接口分组, 重要的连续性的接口, 允许过期不久的 token 进行操作, 比如下单.(等再次打开 app 的时候重新登录)

下策: 颁发的 token 有效期 15 天(举个栗子), 当 app 打开的时候, 客户端自己判断当前距离 token 过期还剩下 8h(自己业务拍个板), 然后提示登录到期, 重新登录

一般彦祖都喜欢选下策 :grin:

8个月前 评论

这个一般是前后端配合解决 Token有效期内,前端每次请求完获取新的token,过期时间自动顺延 如果是有效期内无任何后端交互,那么过期属于正常。

8个月前 评论

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