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  ·  3年前

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

$user_id = JWTAuth::setToken($data_get['token'])->getPayload()->get('sub');
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
最佳答案

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

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

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

我也正在纠结这个。

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

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

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

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

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

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

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

1年前 评论

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