I am trying to use Laravel Sanctum both for API authentication and SPA authentication. In SPA authentication. Do I need to define sanctum/csrf-cookie in api.php? If so, which one would be the correct one? 1 or 2? I got 204 error if I use 1. I got 401 error if I use 2.
Route::get('/sanctum/csrf-cookie', [CsrfCookieController::class, 'show']);Route::middleware('auth:sanctum')->get('/sanctum/csrf-cookie', function (Request $request) { return response()->json(['message' => 'CSRF cookie set']); });
I have uncommented the following line as well.
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
bootstrap.js file
import axios from 'axios';
window.axios = axios;
axios.defaults.withCredentials = true;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
.env file
SANCTUM_STATEFUL_DOMAINS=http://localhost:3000
SESSION_DOMAIN=localhost
The registration function from UserController
public function registration(Request $request) {
$credentials = $request->validate([
'name' => 'required',
'email' => 'required',
'password' => 'required'
]);
// Check if the email is already taken
$existinguser = User::where('email', $credentials['email'])->first();
if($existinguser) {
return response()->json(['error'=>'Email already in use'], 400);
}
$user = new User;
$user->name = $credentials['name'];
$user->email = $credentials['email'];
$user->password = bcrypt($credentials['password']);
$user->save();
return response()->json(['message'=>'User created successfully']);
}
signin function in UserController
public function signin(Request $request) {
$credentials = $request->validate([
'email' => 'required',
'password' => 'required'
]);
if (Auth::attempt($credentials)) {
$user = User::where('email', $credentials['email'])->first();
if ($user && Hash::check($credentials['password'], $user->password)) {
$token = $user->createToken('api-token')->plainTextToken;
return response()->json(['user' => $user, 'token' => $token]);
}
}
return response()->json(['error' => 'Email or password is incorrect'], 401);
}
signout function
public function signout(Request $request) {
$request->user()->tokens()->delete();
return response()->json(['message' => 'Logged Out'], 200);
}
To use the token I receive from signin function as Authorization Bearer, do I store in localStorage? I read somewhere that it is not safe and not a good practice to store the token the token in localStorage.
The following is signin.js file
if(email && password) {
let item={email, password}
try {
await axios.get('http://127.0.0.1:8000/api/sanctum/csrf-cookie')
const response = await axios.post('http://127.0.0.1:8000/api/signin', item, {
withCredentials: true,
})
if(response.status === 200) {
console.log(response)
localStorage.setItem('user_info', response.data.user.name)
localStorage.setItem('api_token', response.data.token)
router.push('/')
} else {
setsigninError('Error registering', error)
console.log('error A')
}
} catch(error) {
setsigninError(error.response.data.error);
console.log(error.response.data.error)
}
}
Is my API authentication using Laravel Sanctum correct?
Lets say I save the token I got from the signin function in the localStorage, I need to use that token in signin request as Authorization Bearer? How can I do that if I get the token after signin request. I really don't understand this.
This is the route I am redirecting after signin.
Route::get('/', [ProductController::class, 'showproduct']);
Please help.
sanctum tokenin yourSignInAPI response? One thing I want to tell you sanctum by default provide API access from of request origin.FRONTEND_URLshould need to set yourLocal React server URLotherwise Laravel will not allow you to access API