I have been trying to implement Laravel sanctum, but I am having this error "CSRF token mismatch" even though I followed everything that is said in the Laravel Sanctum documentation
cors.php
config file
'paths' => [
'api/*',
'login',
'logout',
'sanctum/csrf-cookie'
],
'supports_credentials' => true,
kernal is added as per the documentation, so not wasting space by adding its code here
.env
file
SESSION_DRIVER=cookie
SESSION_DOMAIN=localhost
SANCTUM_STATEFUL_DOMAINS=localhost
I am using Angular 9 as my frontend here
This is my interceptor
request = request.clone({
withCredentials: true
})
This is how I send the request to Laravel
this.http.get<any>(url('sanctum/csrf-cookie')).subscribe(() => {
this.http.post<any>(url('login'), { this.username, this.password })
.subscribe(success => console.log(success), error => console.log(error))
})
Once the first route is hit I can confirm the creation of cookies, but the issue is with the second route ('/login')
You need to send x-csrf-token in the header, (Angular includes it automatically only in relative URLs not absolute)
You can create an interpreter to do this, something like this should work:
import {Injectable} from '@angular/core';
import {
HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpXsrfTokenExtractor
} from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class HttpXsrfInterceptor implements HttpInterceptor {
headerName = 'X-XSRF-TOKEN';
constructor(private tokenService: HttpXsrfTokenExtractor) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.method === 'GET' || req.method === 'HEAD') {
return next.handle(req);
}
const token = this.tokenService.getToken();
// Be careful not to overwrite an existing header of the same name.
if (token !== null && !req.headers.has(this.headerName)) {
req = req.clone({headers: req.headers.set(this.headerName, token)});
}
return next.handle(req);
}
}