4
votes

I have an application that has the following setup:

Laravel

Host: appname.local:8000

Environment variables:

  • SESSION_DRIVER=database
  • SESSION_LIFETIME=480
  • SESSION_CONNECTION=mysql
  • SESSION_DOMAIN=.appname.local
  • SESSION_SECURE_COOKIE=false
  • SESSION_COOKIE=appnameapi_session
  • SANCTUM_STATEFUL_DOMAINS='.appname.local,localhost,127.0.0.1'

Angular

Host: appname.local:4200

What works at the moment:

  • I can call Sanctum's csrf-cookie endpoint which sets the CSRF token in my browser.
  • I then can call my API's login endpoint to authenticate the user in my Laravel app using Auth::attempt(). This create a new entry in the sessions table as seen below

Angular methods to get token and authenticate user Angular methods to get token and login

Session database entry after successful authentication Session database entry after successful authentication

What does not work:

Subsequent requests to routes that are protected by the following middleware: auth:sanctum all result in unauthenticated responses. The HTTP requests never make it to my controllers.

auth:sanctum protected routes auth:sanctum protected routes

But I can see in the developer's console that the cookies are being sent. So I don't understand why Sanctum isn't picking up the auth enter image description here

I've followed several tutorials and I can't seem to understand why Laravel's Authenticate middleware is unable to see that I've already authenticated my user.

Does anyone know what I could be doing wrong?

5
Have you double checked you have all the settings correct as shown in the SPA configuration section?DigitalDrifter
@DigitalDrifter Yes, I did. Stateful configuration takes the value of my env variable 'SANCTUM_STATEFUL_DOMAINS' that I posted in my question. I added sanctum's middleware to the API group and I also completed the CORS & Cookies section as suggested in the docs.Gloire
hi. did you manage to resolve this? I am facing the same issue.Eden WebStudio
@EdenWebStudio Nope. I decided to use normal session based auth for now. I plan to try again once I clear some of my tasks.Gloire
@EdenWebStudio did you manage to solve this? I'm stuck there too :(zinyando

5 Answers

5
votes

The answers provided by @agm1984 and @Eden Webstudio were quite useful. However, they did not solve my issue.

After additional debugging, I noticed that sanctum's guard logic looks for a guard in config/sanctum.php. Its default value is web. My default guard for the protected routes is the api guard which is the guard that I used during the authentication process. enter image description here

After setting the guard key in config/sanctum.php with 'api' the authentication seems to be working smoothly. To be honest, I can't remember why I decided to the session driver for my api guard.

config/sanctum.php config/sanctum.php

config/auth.php

config/auth.php

3
votes

Laravel Sanctum doesn't appear to support wildcard domains for the SPA.

Try removing the dot.

SANCTUM_STATEFUL_DOMAINS='appname.local'

You may need a different solution for wildcard subdomains. You could look at bearer token option. I haven't tested this though.

2
votes

I think Eden is correct. I'm visiting this question for unrelated reasons, but to support subdomains, you can have a dot in SESSION_DOMAIN env variable, but never SANCTUM_STATEFUL_DOMAINS.

Here is a valid env config for both local and production:

./.env

# localhost
SANCTUM_STATEFUL_DOMAINS="angular-site.test"
SESSION_DOMAIN=".angular-site.test"

# production
# SANCTUM_STATEFUL_DOMAINS="hockeysticks.net"
# SESSION_DOMAIN=".hockeysticks.net"

That will allow the cookies to work across multiple subdomains such as auth.hockeysticks.net, product.hockeysticks.net, service.hockeysticks.net, and api.hockeysticks.net.

If a person puts the dot in SESSION_DOMAIN, cookies will still work if there are no subdomains, but it should be theoretically more secure to omit it in that case.

Here is a video by Mohamed Said, a developer at Laravel, talking about Sanctum: https://www.youtube.com/watch?v=Kd3hcrxtTHA. In it, he walks through the authentication logic.

0
votes

I had the same issue. I found the sanctum SPA API works fine if the request is made from an app not set on a port no.

you can host your frontend app on

appname.local

instead of appname.local:4200

0
votes

If you are using localhost for your frontend and backend with different ports like the following:

Angular/Ionic

Host: localhost:8100

Laravel v8

Host: localhost:8000

Try setting your ./env to:

SESSION_DOMAIN=localhost
SANCTUM_STATEFUL_DOMAINS=localhost:8100

Keep in mind, I've set the following after following @Gloire 's answer