当前位置: 首页 > 知识库问答 >
问题:

Laravel广播-无需承载令牌即可访问的私人频道

桑思远
2023-03-14

我有安装插座。io与laravel echo一起加入并收听laravel广播频道。公共频道工作正常,因为它们不需要任何授权。专用通道未按预期工作,我可以使用套接字加入任何专用通道。未传递授权令牌的io客户端。

插座io客户端

window.Echo = new Echo({
    host: "http://127.0.0.1:6001",
    auth:{
        headers: {
            Accept: 'application/json',
            Authorization: 'Bearer ',
        },
    },
    broadcaster: 'socket.io',
});

window.Echo.private('user'+"."+userid)
.listen('Notification', (e) => {
    console.log(e);
})

Laravel Echo服务器配置

{
"authHost": "http://127.0.0.1:8000",
"authEndpoint": "/broadcasting/auth",
"clients": [],
"database": "redis",
"databaseConfig": {
    "redis": {
        "port": "6379",
        "host": "localhost"
    },
    "sqlite": {}
},
"devMode": true,
"host": null,
"port": "6001",
"protocol": "http",
"socketio": {},
"secureOptions": 67108864,
"sslCertPath": "",
"sslKeyPath": "",
"sslCertChainPath": "",
"sslPassphrase": "",
"subscribers": {
    "http": true,
    "redis": true
},
"apiOriginAllow": {
    "allowCors": true,
    "allowOrigin": "localhost",
    "allowMethods": "GET, POST",
    "allowHeaders": "Origin, Content-Type, X-Auth-Token, X-Requested-With, Accept, Authorization, X-CSRF-TOKEN, X-Socket-Id"
}
}

航道

Broadcast::channel('user.{userId}', function ($user, $userId) {
    return (int) $user->id === (int) $userId;
});

广播服务提供商

Broadcast::routes(['middleware' => ['auth:api']]);

用户配置

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
        'hash' => false,
    ],
],

127.0.0.1:8000/无令牌访问时的广播/授权响应

{"message":"Unauthenticated."}

Laravel回声服务器

[4:50:17 PM] - Preparing authentication request to: http://127.0.0.1:8000
[4:50:17 PM] - Sending auth request to: http://127.0.0.1:8000/broadcasting/auth
[4:50:17 PM] - LtnbMInYDGa_QMMcAAAA authenticated for: private-user.1
[4:50:17 PM] - LtnbMInYDGa_QMMcAAAA joined channel: private-user.1

所以我猜laravel echo服务器在响应“未经验证”时不会返回false

任何帮助都将不胜感激

共有1个答案

闻人修明
2023-03-14

好吧,这很有趣。我决定检查laravel echo服务器如何请求“广播/授权”,以及它如何处理该请求的响应。

您可以在这里查看:https://github.com/tlaverdure/laravel-echo-server/blob/master/src/channels/private-channel.ts

因此laravel-echo-server返回true如果广播/授权的响应代码是200,返回false如果响应代码不是200或如果有一个错误的请求。

这里的问题是,当您向通过passport身份验证处理的laravel api路由发送请求时,它确实返回“Unauthenticated”消息,但没有401代码,因此laravel echo服务器认为请求成功,并允许用户加入该通道。

解决方案:

  1. 返回401代码和Passport未经验证的响应
  2. 通道认证中间件

返回401代码与护照未经验证的响应

projectdir\app\Exceptions处理程序。php

...
use Illuminate\Auth\AuthenticationException;

...
public function render($request, Exception $exception)
{
    if($exception instanceof AuthenticationException){
        return response()->json(['message' => $exception->getMessage()], 401);
    }else{
        return response()->json(['message' => $exception->getMessage() ]);
    }

    return parent::render($request, $exception);
}

用于通道认证的中间件

php artisan make:中间件[名称]

Projectdir\app\Http\Middleware[name]. php

use Closure;
use Illuminate\Support\Facades\Auth;

class SocketAuth
{

    public function handle($request, Closure $next)
    {
        $user = Auth::User();

        if($user !== null){
            if($request->channel_name == "private-user.".$user->id){
                return $next($request);
            }else{
                return response()->json(["message" => "Unauthenticated."], 401);
            }
        }

        return response()->json(["message" => "Unauthenticated."], 401);
    }
}

广播服务提供商

Broadcast::routes(["prefix" => "api", 'middleware' => ['auth:api', 'SocketAuth']]);

注册中间件

Projectdir\app\Http Kernel.php

protected $routeMiddleware = [
    ...
    'SocketAuth' => \App\Http\Middleware\SocketAuth::class,
];

Laravel Echo服务器配置

"authEndpoint": "/api/broadcasting/auth",

后果

>

认证200-(Laravel-Echo-Server True)在:[令牌存在于来自客户端的请求和请求的用户通道==请求用户的通道]

您可以将用于验证用户的逻辑应用于中间件中的通道。

 类似资料:
  • 我正在尝试调用我已被指示的API: 这需要一个授权头:承载访问令牌。 我有承载访问令牌,并尝试通过邮递员,并通过C#使用WebRequest,没有任何效果。 在Postman中,我将方法设置为GET,将授权设置为No Auth,在Headers选项卡上,我尝试添加一个标题,如下所示: 标头:“授权” 值:“我的令牌” 我也尝试过 标题:“Bearer”值:“mytoken” 也 标头:“授权” 值

  • 我已经为我的应用程序设置了Pusher和Laravel Echo,以便在某些事件触发时通知用户。 我已经测试过,看看设置是否通过在“公共频道”上播放而工作,并成功地看到这是工作。 以下是活动本身: 公共频道: app/resources/assets/js/bootstrap。js: 和Laravel回声注册:(它是在我的主布局的头部部分,事件射击视图延伸。) 现在,这种设置适用于公共频道广播,但

  • 假设我们使用OAuth承载令牌来保护API。有一个带有OWIN中间件的NuGet包可以为我们做到这一点:https://www.nuget.org/packages/Microsoft.Owin.Security.OAuth. Everethig看起来很棒,直到提出访问令牌过期的问题——我们不想强迫用户一次又一次地重新登录。据我所知,有三种基本方法: 使访问令牌到期时间非常长(例如1个月) 使用O

  • 活动是: 路线/频道。php是: 在刀片文件中: 广播频道工作正常。但在私密频道里,这是行不通的。并且在控制台中没有显示任何错误 我使用拉威尔回声和推进器

  • 我正在尝试使用Laravel护照,我不知道我是否发现了一个bug或者我遗漏了什么。 登录控制器: 因此,我在用户登录时创建令牌。在数据库中,我看到生成的令牌在字段处过期:一周后,所以它是正确的。但如果我更改了旧日期的值,我仍然可以使用此令牌。。。 拉威尔只是忽略了这个领域?为什么? 我做了研究,但我有点困惑。。。很多人说代币不会过期或在一年内过期。但后来我发现了一些关于这个片段的帖子: 我明白To

  • 使用Vue。js我试图用Spring Boot在RESTful API中实现JWT登录表单,但除非我向请求中添加承载令牌,否则我得到的只是403状态。我已经将endpoint设置为无需任何许可即可访问,并且在postman上可以在没有授权标头的情况下发送请求。这是我在Spring上的安全配置的一部分: 这就是vue。我发出发帖请求的js服务: 我想这样做,这样就不需要令牌来访问您请求相同令牌的部分