Skip to content

Instantly share code, notes, and snippets.

@rdehnhardt
Last active August 16, 2023 08:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rdehnhardt/65c5c682bf4ddc950f8a43e10af4b730 to your computer and use it in GitHub Desktop.
Save rdehnhardt/65c5c682bf4ddc950f8a43e10af4b730 to your computer and use it in GitHub Desktop.
Flutter App with Laravel Sanctum (XSRF TOKEN)
import 'package:dio/dio.dart';
import 'package:curl_logger_dio_interceptor/curl_logger_dio_interceptor.dart';
import 'interceptors/csrf_token_interceptor.dart';
class Api {
final Dio dio;
Api(this.dio) : super() {
dio.interceptors.addAll([
CurlLoggerDioInterceptor(),
CsrfTokenInterceptor(dio)
]);
dio.options = BaseOptions(
baseUrl: "http://localhost",
connectTimeout: const Duration(seconds: 5),
receiveTimeout: const Duration(seconds: 3),
headers: {
Headers.acceptHeader: Headers.jsonContentType,
Headers.contentTypeHeader: Headers.jsonContentType,
},
);
}
}
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:core/core.dart';
class AuthenticationApiService extends Api {
AuthenticationApiService(super.dio);
Future<Response> register(String email, String password, String deviceName) async {
return await dio.post('/register',
data: jsonEncode({
'device_name': deviceName,
'password': password,
'email': email,
}),
);
}
}
import 'dart:io';
import 'package:dio/dio.dart';
class CsrfTokenInterceptor extends Interceptor {
final Dio dio;
CsrfTokenInterceptor(this.dio);
@override
Future<void> onRequest(options, handler) async {
List<String> methods = <String>['POST', 'PUT', 'DELETE', 'PATCH'];
if (methods.contains(options.method)) {
final response = await dio.get('/sanctum/csrf-cookie');
if (response.statusCode == HttpStatus.noContent) {
response.headers.forEach((name, values) {
if (name == HttpHeaders.setCookieHeader) {
for (String value in values) {
Cookie cookie = Cookie.fromSetCookieValue(value);
if (cookie.name == 'XSRF-TOKEN') {
options.headers['X-XSRF-TOKEN'] = cookie.value;
}
}
}
});
}
}
return handler.next(options);
}
}
curl -i \
-X POST \
-H "accept: application/json" \
-H "content-type: application/json" \
-H "X-XSRF-TOKEN: eyJpdiI6IlNHK05PblhWNCtrdHdJZXFaQlFWV2c9PSIsInZhbHVlIjoiZFc0RTVtQVVyb24zcm9rcElCMDNXLzBPNmdPUTgrS1d0S3F1VjdjVzJtckRhMVBvQlhNR1hFNm1EVVh3NEdVdjB1ZG84MTNZOHFLM0pDRHRsVUlUbXVoS1VOZm1tQXF4eCtDYkk4ZnA5NU50TkI0Qk1GRnBGeEVFbkYrT0lrbkYiLCJtYWMiOiJlZTg3YTc0ZGEwMjFlNTYzYjlkOWY3YWUxMmIxYjZkOWYyYzI2OGFhNmY5MzJhNTQxNDY4MmZhMjc3MDFhNjFkIiwidGFnIjoiIn0%3D" \
-H "content-length: 103" \
-d "\"{\\"device_name\\":\\"6E7D7E70-501B-4594-ABAF-0D3826B5CE6B\\",\\"password\\":\\"12345678\\",\\"email\\":\\"email@domain.com\\"}\"" \
"http://localhost/register"
@rdehnhardt
Copy link
Author

I don't know what's going on, it seems to me that I'm not passing some information to the API, because even sending the "X-XSRF-TOKEN" in the header I'm getting a return '{"message":"CSRF token mismatch."} '

@fhferreira
Copy link

CSRF generally is related with "Session" on laravel side, to confirm that the request comes from same server, so I think for external, CSRF is not applicable, it should comes from 'API'

@rdehnhardt
Copy link
Author

CSRF generally is related with "Session" on laravel side, to confirm that the request comes from same server, so I think for external, CSRF is not applicable, it should comes from 'API'

the csrf token is coming from the api, in the request “/sanctum/token” is loading the token

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment