Framework: Using both 'web' & 'auth:api' middlewares at the same time for Broadcast Events

Created on 23 Feb 2018  路  6Comments  路  Source: laravel/framework

  • Laravel Version: 5.4
  • PHP Version: 7.2
  • Database Driver & Version: mysql

I am using Laravel Event Broadcast and Pusher to utilize websockets both on my API and Web. If I try them individually, both work. What I mean is:

Broadcast::routes(['middleware' => 'web']); // this works for my Laravel website

Broadcast::routes(['middleware' => 'auth:api']); // this works for my api

However, if I want to use both at the same time like this:

Broadcast::routes(['middleware' => ['auth:api', 'web']]); // doesn't work

... it crashes for both, which I suspect that it is assuming I am trying to enable for both auth:api && web middlewares.

Is there a way to use an OR kind of statement for this (auth::api || 'web')? What if I want to use both at the same time and if it passes one middleware, it bypasses the middleware.


I have found this comment in a Laravel Echo issue, but couldn't replicate it at all.
What I tried is creating a new Middleware called Broadcast and do this accordingly:

class BroadcastMiddleware() {

  public function handle() {
    $web = Auth::guard('web')->user();
    if ($web) {
        return response()->json($web);
    }

    $api = Auth::guard('api')->user();
    if ($api) {
        return response()->json($api);
    }
    return response()->json('Unauthorized.', 500);
  }
}

And also tried setting up a route for /broadcast/auth

Route::post('/realtime/auth', function(){
    return true;
})->middleware('broadcast');

However, using above code, it's returning User model; however instead Laravel's broadcasting/auth return something like: auth:"374f7ff42b7da877aa35:c29addedec281b418331a61dc3cfc74da8b108222565fa4924a8..."

Did any of you faced with a similar issue? How can I overcome this and actually use either of them (web/auth:api)?

_Also please note that I am using Laravel Passport for my api._

Most helpful comment

I needed to resolve same issue, I changed the boot::BroadcastServiceProvider, checking the header "Autentication" in api we need send, but in "web mode" dont it necessary.

<?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() {
        if(request()->hasHeader('authorization')) {
            Broadcast::routes(["middleware" => "auth:api"]); //is for the api clients requests(React Native App in my case)
        } else {
            Broadcast::routes();//is for the web requests
        }

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

** Only remember, the JWT "session" does not persist states, the data session is in the token, you should avoid save data in session in this endpoints

All 6 comments

Here on StackOverflow, I have added my way of solving this, however I'd like to hear any improvements or any other (more elegant) ways of achieving this. Hope it helps someone

I am using Laravel Event Broadcast and redis to utilize websockets both on API (Android App ) and Web.
The solution not worked for me ( i can't connect with web @ api) in the same time.
I can only connect Android app (api) with Broadcast::routes(['middleware' => 'auth:api']); in BroadcastServiceProvider.
Or connect from Web withBroadcast::routes()
But I want to use both at the same time.
I tried all those solutions but not working for me, i created the middleware, the route in web.php
but not working.
I need a help please, If anyone have a solution that work
@sentiasa thanks.

@slim1616 I can't really comment without knowing your code. What is the error you are getting?

This guy's solution seems the nice way to go, in fact I didn't try it personally - https://stackoverflow.com/a/52271897/4705339

Otherwise I am not really sure why my code on SO doesn't work for you.

I needed to resolve same issue, I changed the boot::BroadcastServiceProvider, checking the header "Autentication" in api we need send, but in "web mode" dont it necessary.

<?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() {
        if(request()->hasHeader('authorization')) {
            Broadcast::routes(["middleware" => "auth:api"]); //is for the api clients requests(React Native App in my case)
        } else {
            Broadcast::routes();//is for the web requests
        }

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

** Only remember, the JWT "session" does not persist states, the data session is in the token, you should avoid save data in session in this endpoints

If you just want as me to be able to present user interfaces when loged in with api (dekstop app with some views costumized but not every) you can just have

Route::prefix('1stparty/web')->middleware('scopes:*')
     ->group(base_path('routes/web.php'));

localhost/settings will in example show users name and will check if he is loged in
this will change it to:
localhost/api/1stparty/web/settings and will still work

EDIT: forgot /web

Hi! It's my solution. You can use something like this

BroadcastServiceProvider.php

Route::post('broadcasting/auth', function () {
   $url = request()->hasHeader('Authorization') ? '/api' : '/web';

   $proxy = Request::create($url . '/broadcasting/auth', 'POST', request()->toArray());
   $proxy->headers = request()->headers;

   return app()->handle($proxy)->content();
});

Broadcast::routes(['prefix' => 'web', 'middleware' => ['web']]);
Broadcast::routes(['prefix' => 'api', 'middleware' => ['auth:api']]);
Was this page helpful?
0 / 5 - 0 ratings

Related issues

YannPl picture YannPl  路  3Comments

PhiloNL picture PhiloNL  路  3Comments

Fuzzyma picture Fuzzyma  路  3Comments

CupOfTea696 picture CupOfTea696  路  3Comments

lzp819739483 picture lzp819739483  路  3Comments