To address your question about SPA authentication with Laravel 11 using Sanctum and Socialite for Google authentication, let's break down the solution into manageable steps. We'll cover both email/password authentication and Google OAuth authentication.
1. Setting Up Sanctum for SPA Authentication
First, ensure that Sanctum is properly set up in your Laravel backend. Sanctum provides a simple way to authenticate single-page applications (SPAs) using cookies.
Install Sanctum
composer require laravel/sanctum
Publish Sanctum Configuration
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate
Configure Sanctum
In your config/sanctum.php, ensure the stateful configuration includes your frontend domain:
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'domain-one.com')),
In your config/cors.php, configure CORS to allow your frontend domain:
'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_origins' => ['https://domain-one.com'],
'allowed_methods' => ['*'],
'allowed_headers' => ['*'],
'max_age' => 0,
'supports_credentials' => true,
Middleware
Ensure api middleware group in app/Http/Kernel.php includes EnsureFrontendRequestsAreStateful:
'api' => [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
2. Email/Password Authentication
Create routes and controllers for login and registration.
Routes
In routes/api.php:
use App\Http\Controllers\AuthController;
Route::post('/login', [AuthController::class, 'login']);
Route::post('/register', [AuthController::class, 'register']);
Route::post('/logout', [AuthController::class, 'logout'])->middleware('auth:sanctum');
AuthController
Create AuthController to handle authentication:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
class AuthController extends Controller
{
public function register(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:8|confirmed',
]);
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
return response()->json(['message' => 'User registered successfully']);
}
public function login(Request $request)
{
$request->validate([
'email' => 'required|string|email',
'password' => 'required|string',
]);
if (!Auth::attempt($request->only('email', 'password'))) {
return response()->json(['message' => 'Invalid credentials'], 401);
}
return response()->json(['message' => 'Login successful']);
}
public function logout(Request $request)
{
$request->user()->currentAccessToken()->delete();
return response()->json(['message' => 'Logged out successfully']);
}
}
3. Google OAuth Authentication with Socialite
Install Socialite
composer require laravel/socialite
Configure Socialite
Add your Google credentials to .env:
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GOOGLE_REDIRECT_URI=https://domain-two.com/auth/google/callback
Socialite Routes
In routes/web.php:
use App\Http\Controllers\SocialiteController;
Route::get('/auth/google/redirect', [SocialiteController::class, 'redirectToGoogle']);
Route::get('/auth/google/callback', [SocialiteController::class, 'handleGoogleCallback']);
SocialiteController
Create SocialiteController to handle Google OAuth:
namespace App\Http\Controllers;
use Laravel\Socialite\Facades\Socialite;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
class SocialiteController extends Controller
{
public function redirectToGoogle()
{
return Socialite::driver('google')->stateless()->redirect();
}
public function handleGoogleCallback()
{
$googleUser = Socialite::driver('google')->stateless()->user();
$user = User::firstOrCreate(
['email' => $googleUser->getEmail()],
[
'name' => $googleUser->getName(),
'password' => Hash::make(uniqid()), // Generate a random password
]
);
Auth::login($user);
return redirect('https://domain-one.com'); // Redirect to your SPA
}
}
4. Frontend Integration
In your SvelteKit SPA, you can use the fetch API to interact with your Laravel backend for login, registration, and Google OAuth.
Example Login Request
async function login(email, password) {
const response = await fetch('https://domain-two.com/api/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
credentials: 'include',
body: JSON.stringify({ email, password }),
});
const data = await response.json();
if (response.ok) {
console.log('Login successful:', data);
} else {
console.error('Login failed:', data);
}
}
Example Google OAuth Redirect
function redirectToGoogle() {
window.location.href = 'https://domain-two.com/auth/google/redirect';
}
Conclusion
This setup should allow you to authenticate users using both email/password and Google OAuth in your SvelteKit SPA with a Laravel 11 backend. Ensure you keep an eye on any updates from Google regarding OAuth to make necessary adjustments in the future.