📖 2 minutes read
Laravel’s Sanctum documentation shows the exact pattern for mobile app authentication. Here’s the production-ready implementation:
The Login Endpoint
use App\Models\Account;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;
Route::post('/auth/token', function (Request $request) {
$request->validate([
'email' => 'required|email',
'password' => 'required',
'device_name' => 'required',
]);
$account = Account::where('email', $request->email)->first();
if (! $account || ! Hash::check($request->password, $account->password)) {
throw ValidationException::withMessages([
'email' => ['The provided credentials are incorrect.'],
]);
}
return $account->createToken($request->device_name)->plainTextToken;
});
Why This Pattern Works
- Single query with Hash::check() – Prevents timing attacks by checking both user existence and password in one validation
- ValidationException for API errors – Returns proper JSON:API error format automatically
- Device name tracking – The
device_namefield lets users manage their active sessions (“iPhone 14”, “Work Laptop”, etc.) - plainTextToken – Critical: This is the ONLY time you can retrieve the token. Store it in the mobile app immediately.
Protected Routes
Route::get('/profile', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
Mobile client sends:
Authorization: Bearer {plainTextToken}
Logout Implementation
Route::post('/auth/logout', function (Request $request) {
// Revoke current device token only
$request->user()->currentAccessToken()->delete();
return response()->json(['message' => 'Logged out successfully']);
})->middleware('auth:sanctum');
Leave a Reply