Workerman的Event使用JWT身份认证导致的用户信息共享

以下是WS连接后进行JWT认证和Client绑定的代码

public static function onWebSocketConnect($client_id, $data)
    {
//        \Log::notice('WK:' . json_encode($data));
        $data_get = $data['get'];
        $res = [
            'type' => 'connection',
            'status' => 'error'
        ];
        // 判断token
        if (!isset($data_get['token'])) {
            $res['msg'] = 'Token不存在';
            Gateway::sendToClient($client_id, json_encode($res, JSON_UNESCAPED_UNICODE));
            Gateway::closeClient($client_id);
        } else {
            // 判断格式是否正确
            if (count(explode('.', $data_get['token'])) !== 3) {
                $res['msg'] = 'Token格式错误';
                Gateway::sendToClient($client_id, json_encode($res, JSON_UNESCAPED_UNICODE));
                Gateway::closeClient($client_id);
            } else {
                // 获取登陆的用户
                $user = null;
                $user = auth('api')->setToken($data_get['token'])->user();
                if (!$user) {
                    $res['msg'] = 'Token格式错误';
                    Gateway::sendToClient($client_id, json_encode($res, JSON_UNESCAPED_UNICODE));
                    Gateway::closeClient($client_id);
                } else {
                    $res['status'] = 'success';
                    $res['msg'] = $user->toArray();
                    Gateway::sendToClient($client_id, json_encode($res, JSON_UNESCAPED_UNICODE));
                    Gateway::bindUid($client_id, $user->id);
                }
            }
        }
    }

出现的问题是,当用户1访问后,用户2345…获取到的用户信息全都是用户1的信息,所有的ClientId也都被绑定到了用户1的上边。也就是最核心的这一句
$user = auth('api')->setToken($data_get['token'])->user();
这要第一次setToken后无论后边Token的值如何改变$user都是第一个用户,求解!

附言 1  ·  4年前

解决方案,不生成对象,只使用JWT解析用户ID。

$user_id = JWTAuth::setToken($data_get['token'])->getPayload()->get('sub');
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
最佳答案

猜测问题应该是出在 auth ('api')->setToken () 这一步,常驻进程内存不会释放,在 setToken 方法中是否存在策略如果没有 token 则设置,如果已有则不更新,那么这就会出现你的问题,因为用户 id 已经存在(来自第一次设置的 token)所以将不会更新了,导致后面所有的用户使用的都是使用同一个用户 ID。

而出现这个问题最主要的原因是 Laravel 在常驻进程中没有重新初始化,这意味着在这个进程中 Laravel 已存在的数据将会共享,这样一来在很多场景下会有意想不到的额外问题。

4年前 评论
MyPuppet (楼主) 4年前
yzbfeng 1年前
yzbfeng 2年前
Anoxia (作者) 1年前
讨论数量: 14

我也正在纠结这个。

4年前 评论
MyPuppet (楼主) 4年前

看看auth ('api')->setToken ()->user () 方法实现的代码。不行你可以自己实现一个 jwt 类

4年前 评论
MyPuppet (楼主) 4年前
pan_zoe 4年前
MyPuppet (楼主) 4年前
pan_zoe 4年前

猜测问题应该是出在 auth ('api')->setToken () 这一步,常驻进程内存不会释放,在 setToken 方法中是否存在策略如果没有 token 则设置,如果已有则不更新,那么这就会出现你的问题,因为用户 id 已经存在(来自第一次设置的 token)所以将不会更新了,导致后面所有的用户使用的都是使用同一个用户 ID。

而出现这个问题最主要的原因是 Laravel 在常驻进程中没有重新初始化,这意味着在这个进程中 Laravel 已存在的数据将会共享,这样一来在很多场景下会有意想不到的额外问题。

4年前 评论
MyPuppet (楼主) 4年前
yzbfeng 1年前
yzbfeng 2年前
Anoxia (作者) 1年前

之前一个项目用的passport 没找到可以直接解析 校验token的办法,只能直接转发请求到当前项目的某个接口。。。

2年前 评论

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