Why is sanctum not authenticating me with my cookie?

35 Views Asked by At

When logging in i create a token for the user and then put it in a cookie. I return that cookie to my front-end and then i use that cookie for every other request to my api. The cookie is in the request header when making requests but it stil doesn't work. I still get 401 errors.

Here is my login function:

class LoginController extends Controller
{
    public function handleLogin(Request $request)
    {
        // Get the access token from the request's bearer token
        $accessToken = $request->bearerToken();
        
        // Call Microsoft Graph API to retrieve user information
        $response = Http::withHeaders([
            'Authorization' => 'Bearer ' . $accessToken,
        ])->get('https://graph.microsoft.com/v1.0/me');

        // return response()->json($response->json());
        // exit;

        // Check if the request was successful
        if ($response->successful()) {
            $userData = $response->json();

            // Check if the user exists in your database
            $user = User::where('email', $userData['mail'])->first();

            // If the user doesn't exist, create a new user
            if (!$user) {
                $user = new User();
                $user->username = $userData['displayName'];
                $user->email = $userData['mail'];
                $user->credits = 0;

                // Set the user's role based on their email domain
                if (strpos($userData['mail'], '@landstede.nl') !== false) {
                    $user->role = 'admin';
                } else {
                    $user->role = 'user';
                }
                
                $user->save();
            }

            // Authenticate the user with Sanctum
            $token = $user->createToken('token')->plainTextToken;
            $cookie = cookie('auth-token', $token, 60 * 24, '/', null, true, true, false, 'None');

            // Return cookie with the token
            return response()->json(['message' => 'User authenticated', 'user' => $user], 200)->withCookie($cookie);
        } else {
            // If the request to Microsoft Graph API fails, return an error response
            return response()->json(['error' => 'Failed to retrieve user information from Microsoft Graph API'], $response->status());
        }
    }
}

These are my routes:

Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

Route::middleware('auth:sanctum')->group(function () {
    Route::get('/waitlist', [WaitlistController::class, 'getItems']);
    Route::post('/waitlist/delete/{id}', [WaitlistController::class, 'deleteItem']);
    Route::post('/waitlist/download', [WaitlistController::class, 'download']);

    Route::get('/users', [UserController::class, 'getUsers']);
})->middleware('web');

Route::get('/login', [LoginController::class, 'handleLogin']);

This is my auth cookie: cookie

Here is the request: request header

1

There are 1 best solutions below

2
Harris On

why are you creating a cookie?. Normally Sanctum works is after you write this line

$token = $user->createToken('token')->plainTextToken;

you need to send it in response

return response()->json(['message' => 'User authenticated', 'user' => $user,'token'=>$token], 200);

when you recieve that response in frontend you need to save that token in your local storage and then from the from the from the front end you need to send that token in the request headers back with the next request options.headers["Authorization"] = "Bearer $userToken"; something like that. And fo that you can reuqest interceptors so i can get handled atumatically with every api cal.

To me it looks like you are confusing X-XSRF-TOKEN with user token this is the token you send with every request also like this you can also do this by using intercpetors

like this

if (( state.csrftoken === null || state.csrftoken ==='null')  && config.url != 'sanctum/csrf-cookie'){
      await api.get("sanctum/csrf-cookie").then((res)=>{
        let token =Cookies.get("XSRF-TOKEN")
        LocalStorage.set('csrftoken',token)
      })
    }