Laravel sanctum unauthenticated
Asked Answered
O

16

20

I am using Laravel sanctum in my project with angular as frontend. Getting unauthenticated from the second api request. Please let me know where am I going wrong

Frontend-> 127.0.0.1:4200

Backend-> localhost:8888

.env config

SESSION_DOMAIN=localhost SANCTUM_STATEFUL_DOMAINS=127.0.0.1

Added middleware auth:sanctum to the routes group in api.php

Ref: https://prnt.sc/rm9ejy

Overmatch answered 25/3, 2020 at 4:47 Comment(0)
R
21

For anyone having an Unauthenticated error, please ensure you follow these steps.

  • Send a GET request to /sanctum/csrf-cookie
  • Send a post request to web route /login to get authenticated

After this step, you will be successfully authenticated by auth:sanctum middleware in the WEB route or any resource route that needs CRSF token present.

[Why did this work]
Sending a GET request(empty request) to /sanctum/csrf-cookie enables laravel to send the fresh set cookies command to your browser to set a fresh CRSF token which can be found in your cookies. Axios and most library send this fresh token as part of headers X-XSRF-TOKEN by default, for regular ajax request, please include them explicitly in your headers or in form _token, else your SPA will still hit the 419(token expired) error

Other things to be aware of:

  1. Ensure your SESSION_DOMAIN is set to localhost
  2. SANCTUM_STATEFUL_DOMAIN is set to your sub domain/SPA with the port e.g localhost:8000

For the original question please ensure you maintain same domain. I mean use localhost for both. And set SANCTUM_STATEFUL_DOMAIN = localhost:4200

Edited

Also set SESSION_DRIVER

Readily answered 18/10, 2020 at 21:18 Comment(1)
I think the request to /sanctum/csrf-cookie needs to be a GET request.Danille
I
20

Add your domains, for example my API is running on localhost:8000 my client is running on localhost:3000 so my env setting looks like below

SANCTUM_STATEFUL_DOMAINS=localhost:8000,localhost:3000

also, add your session domain

SESSION_DOMAIN=localhost
Introjection answered 25/5, 2021 at 18:54 Comment(2)
I used custom domain name for calling the backend and frontend like (backend) api.devtest.test (frontend) devtest.test What should be written on SESSION_DOMAIN ?Niersteiner
@Niersteiner .devtest.test (note . at the beginning) – see laravel.com/docs/10.x/sanctum#cors-and-cookiesEndbrain
V
13

Have you checked your Kernel.php? app/Http/Kernel.php

Make sure you uncomment \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, coz by default it is being commented

'api' => [
    \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
    'throttle:api',
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
],
Villa answered 1/11, 2021 at 16:20 Comment(1)
You nailed it! What you are suggesting also is into the docs, check here laravel.com/docs/8.x/sanctum#sanctum-middlewareHolocaust
R
8

Two days of pain and despair to arrive at this conclusion: the Bearer token was not attached to the request, and that was because of my .htaccess configuration.

If you, like me, are not able to authenticate via API token, try to add this line on your .htaccess file in the public directory in your Laravel project:

RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

Right after RewriteEngine On directive.

CREDITS: Laravel not detecting auth token sent in the header and JWT package

Roethke answered 18/11, 2020 at 10:11 Comment(3)
Sanctum doesn’t use token for Stateful auth. It uses cookies.Darlenadarlene
pain and despair, I know how you feel !Paste
Thanks man, The above solution works!! I've wasted a lot of time figuring out on my own.Stylo
T
5

From the screenshot you shared I see your domain is localhost and not 127.0.01, just do:

SANCTUM_STATEFUL_DOMAINS=localhost
Trave answered 31/3, 2020 at 19:24 Comment(0)
H
5

For anyone using Laravel Homestead, use your actual domain.

SANCTUM_STATEFUL_DOMAINS=homestead.test
Hindorff answered 2/6, 2020 at 19:38 Comment(1)
This worked for me when using a dummy domain "app.test" under my computer's /etc/hosts fileIngvar
F
5

Which version are you running? Since V2.4.0 you need to specify the port:

SANCTUM_STATEFUL_DOMAINS=localhost:4200

See this issue for more info.

Facility answered 1/7, 2020 at 8:29 Comment(0)
W
3

Late in the game but just to help those that keep looking for this solution, most of the answers here have some truth, just have to put them together to make it work:

  • ENV file: SESSION_DOMAIN=localhost (or whatever your domains is)
  • in config->sanctum.php->stateful (if not already there): Sanctum::currentApplicationUrlWithPort()
  • in app/Http/Kernel.php API add as very first (this is important) : \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
  • in app/http/kernel API remove if there: \Illuminate\Session\Middleware\StartSession::class,
  • add to your api routes middleware: auth:sanctum

Also worth checking the guard settings under config->sanctum.php

that should do.

Wingspan answered 14/7, 2022 at 15:55 Comment(0)
D
3

In case you have problems when going into production and/or have more than one subdomains and also use https don't forget that the port is 443 instead of the usual 80.

E.g.:

SANCTUM_STATEFUL_DOMAINS=*.example.com:443
SESSION_DOMAIN=.example.com

Lost days trying to figure out why the laravel, the spa or the android app were taking turns to fail, but never working all at the same time, until found that solution.

Dropout answered 26/7, 2022 at 15:4 Comment(0)
S
2

The sanctum stateful domains require the port number as well.

e.g. SANCTUM_STATEFUL_DOMAINS=127.0.0.1:4200

Although in your case your screenshot shows it should be SANCTUM_STATEFUL_DOMAINS=127.0.0.1:4201

Stollings answered 18/8, 2021 at 16:14 Comment(0)
E
1

This worked for me. The solution is adding this to .htaccess of root folder (not only inside the public folder)

# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
Excitant answered 17/2, 2023 at 17:53 Comment(0)
R
0

I had the same solution as Marco, adding the rewrite rule to my htaccess in public fixed it.

RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

FYI I am hosting this on Auzre Web App Service (linux), if anyone else is doing that.

Renfrew answered 1/11, 2021 at 12:43 Comment(0)
U
0

check if you had changed your guard in past. goto config/auth.php check if your provider model is same as your user model (or the model you using) for authentication. in my case i was using different guard and provider.

Uyekawa answered 23/6, 2022 at 6:0 Comment(0)
R
0

In my case, I was sending auth bearer header token to my backend, in an incorrect way. i had a next-JS project. I retrieved the cookie this way: const ACCESS_TOKEN = req.cookies.get('ACCESS-TOKEN'). the problem was that this method would url-encode the value. so that 268|0oyabZ7cPIR8gWbp8a0dRfFHQO5Kl9ocLPhdz8Rdc9f52c31 would be converted to 268%7C0oyabZ7cPIR8gWbp8a0dRfFHQO5Kl9ocLPhdz8Rdc9f52c31 and that would render me unauthenticated. i used decodeURIComponent function on the value and my problem was gone.

Rayon answered 21/4 at 13:24 Comment(0)
G
0

This solution worked for me.

In the app/Http/Kernel.php file and $middlewareGroups, add \Illuminate\Session\Middleware\StartSession::class in the api section as well.

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        // \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],

    'api' => [
        \Illuminate\Session\Middleware\StartSession::class, // <========
        \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
        'throttle:api',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
];
Gosse answered 22/5 at 9:8 Comment(0)
P
0

I think comments covered a big portion of the possible reasons, so I'm gonna just give a little tip because I've struggled with this and the answer was just to make sure that you didn't forget to add api/ before the actual API route.

Pharisaic answered 6/8 at 21:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.