You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel Passport中通过Token手动认证WebSocket用户

Laravel WebSocket 自定义处理器的认证实现

根据你提供的代码,要完成WebSocket连接时的用户认证,你可以按照以下步骤实现:

1. 完善Token验证与用户获取逻辑

根据你项目使用的Laravel认证方案,选择对应的方式解析Token并获取用户:

情况一:使用Laravel Sanctum

如果项目用Sanctum处理API认证,可通过Token关联查询用户:

<?php

namespace App\SocketServer;

use App\Models\User;
use Ratchet\ConnectionInterface;
use BeyondCode\LaravelWebSockets\WebSockets\WebSocketHandler;
use Illuminate\Support\Facades\Auth;

class SocketHandler extends WebSocketHandler
{
    public function onOpen(ConnectionInterface $connection)
    {
        parent::onOpen($connection);
        $guzzleRequest = $connection->httpRequest;
        parse_str($guzzleRequest->getUri()->getQuery(), $getParameters);

        $token = $getParameters['token'] ?? null;
        if (!$token) {
            $connection->close(401, 'Token required');
            return;
        }

        // 通过Sanctum Token哈希值匹配用户
        $user = User::whereHas('tokens', function ($query) use ($token) {
            $query->where('id', hash('sha256', $token));
        })->first();

        if (!$user) {
            $connection->close(401, 'Invalid token');
            return;
        }

        // 登录用户并绑定到连接属性
        Auth::login($user);
        $connection->user = $user;
    }
}

情况二:使用Laravel Passport

如果用Passport个人访问令牌,借助资源服务器验证Token:

<?php

namespace App\SocketServer;

use App\Models\User;
use Ratchet\ConnectionInterface;
use BeyondCode\LaravelWebSockets\WebSockets\WebSocketHandler;
use Illuminate\Support\Facades\Auth;
use League\OAuth2\Server\ResourceServer;

class SocketHandler extends WebSocketHandler
{
    protected $resourceServer;

    // 依赖注入Passport资源服务器
    public function __construct(ResourceServer $resourceServer)
    {
        $this->resourceServer = $resourceServer;
    }

    public function onOpen(ConnectionInterface $connection)
    {
        parent::onOpen($connection);
        $guzzleRequest = $connection->httpRequest;
        parse_str($guzzleRequest->getUri()->getQuery(), $getParameters);

        $token = $getParameters['token'] ?? null;
        if (!$token) {
            $connection->close(401, 'Token required');
            return;
        }

        try {
            // 构造带Token的请求并验证
            $request = $guzzleRequest->withHeader('Authorization', "Bearer {$token}");
            $psrRequest = \Illuminate\Http\Request::createFromBase($request)->toPsrRequest();
            $validated = $this->resourceServer->validateAuthenticatedRequest($psrRequest);
            
            $user = User::find($validated->getAttribute('oauth_user_id'));
            if (!$user) {
                throw new \Exception('User not found');
            }

            Auth::login($user);
            $connection->user = $user;
        } catch (\Exception $e) {
            $connection->close(401, $e->getMessage());
            return;
        }
    }
}

情况三:自定义Token认证

如果是自己实现的Token逻辑(比如存在users表的api_token字段):

<?php

namespace App\SocketServer;

use App\Models\User;
use Ratchet\ConnectionInterface;
use BeyondCode\LaravelWebSockets\WebSockets\WebSocketHandler;
use Illuminate\Support\Facades\Auth;

class SocketHandler extends WebSocketHandler
{
    public function onOpen(ConnectionInterface $connection)
    {
        parent::onOpen($connection);
        $guzzleRequest = $connection->httpRequest;
        parse_str($guzzleRequest->getUri()->getQuery(), $getParameters);

        $token = $getParameters['token'] ?? null;
        if (!$token) {
            $connection->close(401, 'Token required');
            return;
        }

        // 通过自定义Token字段查询用户
        $user = User::where('api_token', $token)->first();
        if (!$user) {
            $connection->close(401, 'Invalid token');
            return;
        }

        Auth::login($user);
        $connection->user = $user;
    }
}

2. 关键注意事项

  • 不要直接抛出Exception,调用$connection->close()返回错误码和信息,前端能明确捕获连接关闭原因。
  • 将用户对象绑定到$connection->user后,后续onMessage、onClose等方法可直接通过该属性获取当前连接的用户信息。
  • 确保User模型已实现对应认证逻辑(比如Sanctum的HasApiTokens trait)。

内容的提问来源于stack exchange,提问作者Мохамед Русланович

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 18:54:52