带有推送器和 laravel 的实时反应网络应用程序

Real time react web app with pusher and laravel

我想使用 pusher 进行实时聊天,它可以在 public 频道正常工作,但是当我使用私人频道时,我收到了这个错误:

pusher.js:1333 Cross-Origin Read Blocking (CORB) blocked cross-origin response http://20.30.0.236:8000/login with MIME type text/html

这是 laravel 代码:

事件:

use Dispatchable, InteractsWithSockets, SerializesModels;

/**
 * Create a new event instance.
 *
 * @return void
 */
public $user;
public $message;

public function __construct(User $user, Message $message)
{
    $this->user = $user;
    $this->message = $message;
}

/**
 * Get the channels the event should broadcast on.
 *
 * @return \Illuminate\Broadcasting\Channel|array
 */
public function broadcastOn()
{
    return new PrivateChannel('chat');
}

channels.php :

    Broadcast::channel('private-chat', function ($user) {
    return true;
});

广播服务提供商:

  class BroadcastServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Broadcast::routes(['middleware' => ['auth:api']]);

        require base_path('routes/channels.php');
    }
}

这是反应 js 代码:

  export const onChatRcv = () => {
    try {
        Pusher.logToConsole = true;

        var pusher = new Pusher('83*********63c912f5', {
            cluster: 'ap2',
            forceTLS: true,
            authTransport: 'jsonp',
            authEndpoint: `${baseUrl}broadcasting/auth`,
            headers: {
                'Authorization' : `Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjRhZTA1YjM2ZGNhN2I5NWI4NTJiZjFhOWRiZTQ5ZWE1NzFmNTNkMTE4NWQyOWU0Mjk0ZDI5NmJmZThhZTE0OGQzNzcwODM1MjEzYTg2NzA1In0.eyJhdWQiOiIxIiwianRpIjoiNGFlMDViMzZkY2E3Yjk1Yjg1MmJmMWE5ZGJlNDllYTU3MWY1M2QxMTg1ZDI5ZTQyOTRkMjk2YmZlOGFlMTQ4ZDM3NzA4MzUyMTNhODY3MDUiLCJpYXQiOjE1NTExMDQ3NTYsIm5iZiI6MTU1MTEwNDc1NiwiZXhwIjoxNTgyNjQwNzU2LCJzdWIiOiI1Iiwic2NvcGVzIjpbXX0.HOnNyhQQ48Hj4AZdP5vS5Zd5AfUr5XNP4zgrgR_f2-aAgFw4eWrNeHQSfdJt071_ChRINmv5W7O1LExxGIvCoSjiYFYPmw_8WjdFI_81WHoqM69ve-bgriK6eO1Yf0N3v3fc1DvPk2ZFYXXDmQbMLLXUyUqfjoYGty8AMgxCDulZ1tRMZ2rOVQZJ0ePbTw1eHQdMzBWG36fXWEbczLR99-_Dn8ta8P6iq0XWDr0cimlFzdHsG66iMeI0xWCJ1DRbxzr2LuX0j5zKe0j0_WNZJNbAFfeY87m7FDHjbHTNB1IB9Meh8kITV1mPQLc2n812j2QgW19KKWgpgZcy4tlfIBfT0x-aQAMkIUtmcHW0aEJ8RkHWKZYhyQ8yV61RIL3IxLpepHUVds8CZnxDGQ2NQ4bmb8UE7xQkV-KpmF5fZ0NCCxMuMpYdVkd0t9gc_Jra07_Sq7HbEJHEZbPCfhbDscAZQr2U9ddVaKwiGuFjSGXvOKS_lUAB91lBWada3k15FG2XoBfAv94mai2aWo41sep0nmlBKXPCVbWiczbeNL6ZXm_aE-tkLNS-Pc0veXogxZIaKVhFnRsW5qHTXI8v6sU6Nd9pzrIe173FqXQtzpA_tqrmdWU-lU-u484hWkPn2OcQcSckANpx-7_EVhrAPSfV7-WWamMRp2EC-3uFpmQ`,
            },
        });

        var privateChannel = pusher.subscribe('private-chat' );
        privateChannel.bind('App\Events\MessageSent', function(data) {
            console.log(data);
        });

    } catch (error) {
        console.error(error);
    }
}

有什么问题? 它在我们使用 public 频道时有效,但在私人频道中,我们收到此警告

Cross-Origin Read Blocking (CORB) blocked cross-origin response http://20.30.0.236:8000/login with MIME type text/html

您可以将访问私人频道视为向服务器发出私人授权请求。 由于安全原因,您不能直接访问 react 的私人频道。 如 CodeAcademy 中所述....

Servers are used to host web pages, applications, images, fonts, and much more. When you use a web browser, you are likely attempting to access a distinct website (hosted on a server). Websites often request these hosted resources from different locations (servers) on the Internet. Security policies on servers mitigate the risks associated with requesting assets hosted on different server

您的 laravel 应用中需要一个策略来添加 CORS(跨源请求共享) 最初它有点复杂但是你可以使用这个 library.

现在您可以向 laravel 应用发出任何类型的私人请求。

PS

不要忘记在 channels.php 中的广播路由中添加检查,因为您只是在没有任何检查的情况下简单地返回 true。

默认路由 broadcasting/auth 无法检索到合适的响应,因此我添加了自定义 authEndPoint.

web.php:

Route::get('pusher/auth', 'PusherController@pusherAuth');

并添加了 PusherController:

class PusherController extends Controller
{
    /**
     * Authenticates logged-in user in the Pusher JS app
     * For presence channels
     */
    public function pusherAuth()
    {

        $user = auth()->user();

        if ($user) {
            $pusher = new Pusher('auth-key', 'secret', 'app_id');
            $auth= $pusher->socket_auth(Input::get('channel_name'), Input::get('socket_id'));
            $callback = str_replace('\', '', $_GET['callback']);
            header('Content-Type: application/javascript');
            echo($callback . '(' . $auth . ');');
            return;
        }else {
            header('', true, 403);
            echo "Forbidden";
            return;
        }
    }
}

这有效并订阅了频道。