Summer Sale! All accounts are 50% off this week.

tommybuns's avatar

Laravel Passport - Store token in cookies

I am using Laravel 5.8 and Passport 7.3.

I am using Passport with https://laravel.com/docs/5.8/passport#password-grant-tokens, strictly. I am not using any of the oAuth features at all.

The set up I want is to make an API request from an SPA from domain.com to my Laravel instance on api.domain.com using Cookies.

I have managed to get this working (but not in the way I want), to prove my set up is working end to end.

When you hit api/auth/login, I authenticate the User and return a cookie that contains:

$token = $user->createToken('MyApp')->accessToken;

I am using NextJS for the front-end, which allows me to get the Cookie from the Headers sent to my Express server that is being used to run NextJS, I then pass this to my React Component that sends it off in the Authorization: Bearer header.

Using this method I can pass `->middleware('auth:api').

Now, I want to change from Authorization: Bearer to just passing the secure, httpOnly cookies they already have stored, so I can make API calls from the client.

The docs talked about passing the Authorization: Bearer, but do not mention cookies. https://laravel.com/docs/5.8/passport#protecting-routes

The docs show how to pass the token via Cookies, but my API is only a completely server, so my web routes are never used as the API is headless. https://laravel.com/docs/5.8/passport#consuming-your-api-with-javascript

How do I make it so my API routes read the Cookies sent, and have the authorization check against that, instead of Authorization: Bearer when using ->middleware('auth:api'), Auth::logout() etc?

0 likes
9 replies
bobbybouwmann's avatar

As far as I know your cookie should only be there for reading purposes and not for something else. You need to extract the value to send it along as the header.

An alternative option is overriding the auth:api middleware with your own check on the cookie instead of the header.

Here is also an tutorial on how to properly set up an API with passport being very secure: http://esbenp.github.io/2017/03/19/modern-rest-api-laravel-part-4/

2 likes
tommybuns's avatar

@BOBBYBOUWMANN - What is involved in overriding the auth:api middleware?

Would I have to create a new class that implements Guard? I see Auth/Middleware/Authenticate has an authenticated() function that runs guard()->check().

Ideally I just need to swap checking Headers: Authorization for checking Cookies for the token instead.

Hopefully there's a way to do that without having to write a Guard from the ground up?

bobbybouwmann's avatar
Level 88

Laravel comes by default with the Authenticate middleware. In there you should be able to check on the cookie and perform some check on the user if it's authenticated or not.

Or simply convert the cookie to a header in your middleware

// app\Http\Middleware\Authenticate.php

public function handle($request, Closure $next, ...$guards)
{
    if ($request->cookie('cookie-name')) {
        $request->headers->set('Authorization', 'Bearer ' . $request->cookie('cookie-name'));

    }

    $this->authenticate($request, $guards);

    return $next($request);
}

Note: I didn't test this but it should point you in the right direction!

4 likes
tommybuns's avatar

A lot had to be tweaked and tested afterward, but that solution was perfect for me. I moved it to a middleware that runs globally on every request so authentication is left as it is out of the box.

It's rare you get exactly what you were looking for! Thanks a lot @bob

1 like
tommybuns's avatar

@BOBBYBOUWMANN - Have you encountered any issues further down the road?

I feel like I am potentially abusing Passport and using it as a pseudo-session storage as I am the only, first class, consumer of the API. I am only doing it so I can use React instead of Blade templates.

I damn near went for just using sessions as normal but with an entirely React front-end.

bobbybouwmann's avatar

So far no problems. If authentication works fine than the only thing that remains are the api routes ;)

Please or to participate in this conversation.