Search code examples
vuejs3laravel-echopusher-js

What can I do to resolve this pusher error-JSON returned from auth endpoint was invalid, yet status code was 200?


I still have this problem after asking the same question here: JSON returned from auth endpoint was invalid, yet status code was 200 with no response. I've looked at similar questions and followed the suggestions: setting my broadcast driver to 'pusher', uncommenting 'App/BroadcastServiceProvider' class in my app.config file, setting debug mode to false in my .env file, etc. I have also looked at pusher docs but the issue remains unresolved for me.

I have updated my previous attempt by adding '/broadcasting/auth/' auth endpoint and headers but still the same error. But I can now see a 302 redirect to the auth route then a 302 redirect to the login route then to the dashboard with a 200 response on laravel telescope, which I wasn't seeing before now. So this suggests to me that adding the auth endpoint ought to resolve the issue but it doesn't.

I also tried setting up and using a '/pusher/auth/' auth end point route and controller but it gave me a 'Failed to load resource: the server responded with a status of 405 (Method Not Allowed)' along with "Error: Unable to retrieve auth string from auth endpoint - received status: 405 from /pusher/auth, but not the previous invalid json error. I get this with a 'get' request to the controller but a 500-internal server error with a 'post' request. I really don't know which is correct.

This is my bootstrap.js file:

import Echo from 'laravel-echo';

window.Pusher = require('pusher-js');

// Enable pusher logging - don't include this in production
Pusher.logToConsole = true;

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: process.env.MIX_PUSHER_APP_KEY,
    cluster: process.env.MIX_PUSHER_APP_CLUSTER,
    forceTLS: true,
    authEndpoint: '/broadcasting/auth',
    //authEndpoint: '/pusher/auth',
    auth: {
        headers: {
            'X-CSRF-TOKEN': '{{ csrf_token() }}',
        }
    }
});

This is one pusherController I created:

public function pusherAuth(Request $request)
    {

        $key = getenv('PUSHER_APP_KEY');
        $secret = getenv('PUSHER_APP_SECRET');
        $app_id = getenv('PUSHER_APP_ID');

        $pusher = new Pusher($key, $secret, $app_id);
        $auth = $pusher->socket_auth($_GET('channel_name'), $_GET('socket_id'));
        
        return response($auth, 200);
}

I now know my vue frontend file that should receive and display the broadcast checks out and the issue has to do with resolving this pusher subscription error.

Any help will be appreciated.


Solution

  • I was finally able to resolve this issue. The problem was entirely an authentication issue as the error messages pointed out. While I still don't know why the built in '/broadcast/auth' endpoint didn't work, my initial attempt to authenticate by creating a '/pusher/auth/' was wrong in the way I set up the route and controller.

    The correct route set up should be 'post' and call a controller, using a closure based route didn't work for me. My previous (see above) implementation of the controller was also wrong.

    This is the controller code that worked:

    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    use Pusher\Pusher;
    
    class PusherController extends Controller
    {
         /**
         * Authenticates logged-in user in the Pusher JS app
         * For private channels
         */
        public function pusherAuth(Request $request)
        {
    
            $user = auth()->user();
            $socket_id = $request['socket_id'];
            $channel_name =$request['channel_name'];
            $key = getenv('PUSHER_APP_KEY');
            $secret = getenv('PUSHER_APP_SECRET');
            $app_id = getenv('PUSHER_APP_ID');
    
            if ($user) {
         
                $pusher = new Pusher($key, $secret, $app_id);
                $auth = $pusher->socket_Auth($channel_name, $socket_id);
    
                return response($auth, 200);
    
            } else {
                header('', true, 403);
                echo "Forbidden";
                return;
            }
        }
    }
    

    This is the final bootstrap.js file:

    import Echo from 'laravel-echo';
    
    window.Pusher = require('pusher-js');
    
    // Enable pusher logging - don't include this in production
    Pusher.logToConsole = true;
    
    window.Echo = new Echo({
        broadcaster: 'pusher',
        key: process.env.MIX_PUSHER_APP_KEY,
        cluster: process.env.MIX_PUSHER_APP_CLUSTER,
        forceTLS: true,
        authEndpoint: '/pusher/auth',
        auth: {
            headers: {
                'X-CSRF-TOKEN': '{{ csrf_token() }}',
            }
        }
    });
    

    And my route code in web.php:

    Route::post('/pusher/auth', [PusherController::class, 'pusherAuth'])
    ->middleware('auth');
    

    Pusher console log: Pusher : : ["Event recd",{"event":"pusher_internal:subscription_succeeded","channel":"private-user.3","data":{}}] vendor.js:41325 Pusher : : ["No callbacks on private-user.3 for pusher:subscription_succeeded"]