403 Forbidden on /broadcasting/auth with Sanctum and custom API prefix #55901
Unanswered
mawuli-agbenyo-creator
asked this question in
Q&A
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Laravel Version
12.10.2
PHP Version
8.3.11
Database Driver & Version
No response
Description
When using Sanctum with API token authentication and configuring
Broadcast::routes()
with a custom prefix (e.g.,api
) and middleware['auth:sanctum']
, the/api/broadcasting/auth
route returns a 403AccessDeniedHttpException
.Even with valid tokens and a verified user (via
Auth::check()
), access is still denied.The route is correctly listed via
php artisan route:list
:Steps To Reproduce
POST | api/broadcasting/auth | ... Illuminate\Broadcasting\BroadcastController@authenticate
`// Enhanced pusherSetup.tsx for third-party Pusher
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
import { API_BASE_URL } from '@/constants/config';
// Disable Pusher logs for production
// Pusher.logToConsole = DEV; // Only log in development
// Make Pusher available on window
// @ts-ignore
window.Pusher = Pusher;
// Pusher Configuration - Replace with your Pusher app credentials
const PUSHER_APP_KEY = ''; //
const PUSHER_CLUSTER = 'us2'; // Your Pusher cluster (e.g., 'us2', 'eu', 'ap3')
const createEcho = (userToken: string): Echo | null => {
console.log(
Creating Echo instance with Pusher and token: ${userToken}
);if (!userToken) {
console.error('User token is required to create Echo instance');
return null;
}
try {
return new Echo({
broadcaster: 'pusher', // Changed from 'reverb' to 'pusher'
key: PUSHER_APP_KEY,
cluster: PUSHER_CLUSTER,
forceTLS: true, // Always use TLS with Pusher
encrypted: true, // Always encrypt with Pusher
} catch (error) {
console.error('Error creating Echo instance:', error);
return null;
}
};
// Alternative simplified configuration if you don't need custom auth
export const createEchoSimple = (userToken: string): Echo | null => {
if (!userToken) {
console.error('User token is required to create Echo instance');
return null;
}
try {
return new Echo({
broadcaster: 'pusher',
key: PUSHER_APP_KEY,
cluster: PUSHER_CLUSTER,
forceTLS: true,
auth: {
headers: {
'Authorization':
Bearer ${userToken}
,}
}
});
} catch (error) {
console.error('Error creating simple Echo instance:', error);
return null;
}
};
// Default export
export default createEcho;`
Register broadcast routes like this
`<?php
// app/Providers/BroadcastServiceProvider.php
namespace App\Providers;
use Illuminate\Support\Facades\Broadcast;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\ServiceProvider;
class BroadcastServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*/
public function boot(): void
{
}
const setupReverb = async (userToken: any) => {
try {
console.log('Setting up Pusher connection...');
};
routes/channel.php
<?phpuse App\Models\Conversation;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Broadcast;
use Illuminate\Support\Facades\Log;
Broadcast::channel('App.Models.User.{id}', function ($user, $id) {
Auth::check();
return (int) $user->id === (int) $id;
});
// Authorize conversation channels
Broadcast::channel('conversation.{conversationId}', function ($user, $conversationId) {
// Check if user is participant in this conversation
Auth::check();
});
// Optional: Presence channel for online status
Broadcast::channel('conversation-presence.{conversationId}', function ($user, $conversationId) {
$conversation = Conversation::find($conversationId);
});`
Beta Was this translation helpful? Give feedback.
All reactions