【问题标题】:Laravel /broadcasting/auth Always Fails With 403 ErrorLaravel /broadcasting/auth 总是失败并出现 403 错误
【发布时间】:2017-06-03 09:25:51
【问题描述】:

我最近深入研究了 Laravel 5.3 的 Laravel-Echo 和 Pusher 组合。我已成功设置公共频道并转到私人频道。 Laravel 从 /broadcasting/auth 路由返回 403 时遇到问题,无论我做什么来尝试授权操作(直到并包括使用简单的 return true 语句)。谁能告诉我我做错了什么?

App/Providers/BroadcastServiceProvider.php:

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Broadcast;

class BroadcastServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Broadcast::routes();

        /*
         * Authenticate the user's personal channel...
         */
        Broadcast::channel('App.User.*', function ($user, $userId) {
            return true;
        });
    }
}

资源/资产/js/booststrap.js:

import Echo from "laravel-echo"

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: 'My-Key-Here'
});

window.Echo.private('App.User.1')
    .notification((notification) => {
        console.log(notification.type);
    });

我可以在我的 Pusher 调试控制台中看到该事件及其有效负载,一旦它到达身份验证路由,它就会失败。

【问题讨论】:

    标签: php laravel pusher laravel-echo


    【解决方案1】:

    Error 403 /broadcasting/auth with Laravel version > 5.3 & Pusher,你需要在 resources/assets/js/bootstrap.js 中更改代码

    window.Echo = new Echo({
        broadcaster: 'pusher',
        key: 'your key',
        cluster: 'your cluster',
        encrypted: true,
        auth: {
            headers: {
                Authorization: 'Bearer ' + YourTokenLogin
            },
        },
    });
    

    并在 app/Providers/BroadcastServiceProvider.php 中更改

    Broadcast::routes()
    

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

    Broadcast::routes(['middleware' => ['jwt.auth']]); //if you use JWT
    

    它对我有用,希望对你有所帮助。

    【讨论】:

    • 仅当您使用 API 令牌时才相关。
    • 我在使用护照身份验证时遇到了同样的问题,我只是授权熊令牌。现在它修复了
    【解决方案2】:

    我通过创建通道路由来解决它。

    在 routes->channels.php 中创建您的授权渠道

    Broadcast::channel('chatroom', function ($user) {
        return $user;
    });
    

    查看文档:https://laravel.com/docs/5.4/broadcasting#authorizing-channels

    谢谢

    【讨论】:

    • 你链接的文档说通道方法应该包括...一个返回true或false的回调...,那么你为什么return $user?跨度>
    • @Don'tPanic 因为对于出席频道,您应该返回有关用户的信息,而不是布尔值
    • @MikelGranero 谢谢,我现在看到Authorizing Presence Channels 部分描述了这一点。 OP的问题是关于私人频道AFAICT,而不是存在,所以我不确定这个答案有什么帮助,但我学到了一些东西:-)
    【解决方案3】:

    我将 socket.io 与 redis 配对,并且还遇到了 403 错误的问题,即使 /broadcasting/auth 路由上没有任何身份验证中间件。只是在laracasts lesson之后我发现只有通道授权是不够的,总是应该有用户,无论你如何认证和获取用户,使用默认的 laravel auth 或一些令牌算法 - jwt 或其他任何东西。

    经过身份验证的用户会自动解析并作为第一个参数传递给 routes/channels.php 文件中的闭包函数,因此您可以检查当前登录用户的通道可用性

    【讨论】:

    • 感谢您的回答。但是如果我使用自己的 Auth 中间件,如何将这个授权用户传递给闭包函数呢?
    • 答案不是解决方案。我正在使用 sanctum 并在 Auth::routes() 中使用它,但仍然出现该错误
    【解决方案4】:

    对我有用的是使用 Laravel Echo 包的 private 方法: https://laravel.com/docs/5.3/notifications#listening-for-notifications

    Echo.private('App.User.1')
      .notification((notification) => {
      console.log(notification.type);
    });
    

    【讨论】:

      【解决方案5】:

      在我的情况下,问题是用户 ID 错误:

      Echo.private('user.'+CURRENT_USER_ID_HERE)
      

      【讨论】:

      • 你救了我:)。谢谢。
      【解决方案6】:

      检查您对频道的授权方式。根据您的设置,这可能会有所帮助。使用以下内容更新您的 BroadcastServiceProvider:

      <?php
      
      namespace App\Providers;
      
      use Illuminate\Support\ServiceProvider;
      use Illuminate\Support\Facades\Broadcast;
      
      class BroadcastServiceProvider extends ServiceProvider
      {
          /**
           * Bootstrap any application services.
           *
           * @return void
           */
          public function boot()
          {
              Broadcast::routes(['middleware' => ['auth:api']]);
      
              require base_path('routes/channels.php');
          }
      }
      

      添加用于 Laravel Passport 的 Auth API 中间件。

      【讨论】:

      • 这给了我一个 302(找到)状态:/
      【解决方案7】:

      如果您不再登录,可能会发生这种情况。请确保您确实已登录 Laravel 应用并且您当前的会话没有过期。

      我重新登录,它对我有用。

      【讨论】:

        【解决方案8】:

        如果有人在最​​新的 Laravel 5.7 中遇到同样的问题,对我来说很好的解决方案是在返回之前或在返回时检查每个通道中的身份验证,如下所示。

        Broadcast::channel('user.*', function ($user) {
            return Auth::check();
        });
        
        Broadcast::channel('conversation.{id}', function ($user, $conversationId) {
            Auth::check();
            return $user->isInConversation(Conversation::find($conversationId));
        });
        

        这样,它适用于广播任何事件的任何频道,包括用户。

        我希望它可以帮助别人。

        【讨论】:

          【解决方案9】:
          -- reinstalling websockets
          -- php artisan optimize:clear
          

          【讨论】:

          • 代码转储不能提供好的答案。你应该解释如何为什么这可以解决他们的问题。我推荐阅读,“How do I write a good answer?"
          猜你喜欢
          • 2021-04-08
          • 1970-01-01
          • 1970-01-01
          • 2013-12-21
          • 2014-04-10
          • 2021-02-19
          • 2014-05-22
          • 2018-05-18
          • 1970-01-01
          相关资源
          最近更新 更多