laravel / sanctum

Laravel Sanctum provides a featherweight authentication system for SPAs and simple APIs.
https://laravel.com/docs/sanctum
MIT License
2.75k stars 296 forks source link

Sanctum doesn't work with sub domains #156

Closed jamesh-purr closed 4 years ago

jamesh-purr commented 4 years ago

Description:

Sub domains don't appear to work at all. I have followed the documentation to the T. From the documentation I should be able to use Laravel's auth scaffolding as per normal.

Then when you do an axios call to the api routes using sanctum middleware, it should grab the session/cookie and do the authentication based on the auth scaffolding/ the user logging as per the standard login controller.

Have I misunderstood the way the SPA part works? Apologies if I have.

Steps To Reproduce:

  1. New laravel app with a sub domain on valet - composer install sanctum
  2. Add the SANCTUM_STATEFUL_DOMAIN in the env with the parent domain e.g video.mysite.test
  3. Add SESSION_DOMAIN to env .mysite.test
  4. Add axios.defaults.withCredentials = true; to bootstrap.js
  5. Add the additional kernel code based on the docs
  6. Add sanctum middleware to api.php : Route::group(['middleware' => 'auth:sanctum'], function () {
  7. Try and do a api call with axios, you will get 401 Unauthorized

I have checked the documentation about 40 times and checked forums without any luck of getting a sub domain to work with api calls with Vue. Again apologies If I have misunderstood the way this works. If I have misunderstood, please point me in the right direction.

driesvints commented 4 years ago

Hey there,

Can you first please try one of the support channels below? If you can actually identify this as a bug, feel free to report back and I'll gladly help you out and re-open this issue.

Thanks!

jamesh-purr commented 4 years ago

Hello driesvints,

I have tried larachat(laravel slack community) and stackoverflow(https://stackoverflow.com/questions/62269976/laravel-sanctum-auth-issue/62288791#62288791) without any joy

I have been trying to get this working for two days now :(. I appreciate any help you can give. Its proberly something I am doing wrong but i just cant see it.

RahulDey12 commented 4 years ago

@jamesh-purr you need token In order to authenticate via sanctum middleware

jamesh-purr commented 4 years ago

That would go against what the documentation states

https://laravel.com/docs/7.x/sanctum#spa-authentication

For this feature, Sanctum does not use tokens of any kind. Instead, Sanctum uses Laravel's built-in cookie based session authentication services. This provides the benefits of CSRF protection, session authentication, as well as protects against leakage of the authentication credentials via XSS. Sanctum will only attempt to authenticate using cookies when the incoming request originates from your own SPA frontend.

As long as i'm using laravel's auth scaffolding I can use the cookie based authentatication??

jamesh-purr commented 4 years ago

Hey there,

Can you first please try one of the support channels below? If you can actually identify this as a bug, feel free to report back and I'll gladly help you out and re-open this issue.

* [Laracasts Forums](https://laracasts.com/discuss)

* [Laravel.io Forums](https://laravel.io/forum)

* [StackOverflow](https://stackoverflow.com/questions/tagged/laravel)

* [Discord](https://discordapp.com/invite/KxwQuKb)

* [Larachat](https://larachat.co)

* [IRC](https://webchat.freenode.net/?nick=laravelnewbie&channels=%23laravel&prompt=1)

Thanks!

Hey sorry, I just noticed I didn't reply to you, so I'm not sure you get notifications if I don't reply. Please see above if you didn't and apologies if you do get notifications.

RahulDey12 commented 4 years ago

@jamesh-purr for the SPA authentication you need to add EnsureFrontendRequestsAreStateful at the top of your api middleware in kernel file. Then you have to use web middleware not sanctum.

jamesh-purr commented 4 years ago

Hey @RahulDey12

Thanks for getting back to me. Unfortunately that still doesn't work. I have tried,

Route::group(['middleware' => 'auth:web'], function () { Route::group(['middleware' => 'auth'], function () { Route::group(['middleware' => 'auth:api'], function () {

in my api routes file and still I got unauthorised. The only way I have managed to get this to work is to add this to web.php file instead


Route::prefix('api')->group(function () {
        Route::get('/event/{event}/get-sponsors', 'Api\EventSponsorController@index');
        Route::get('/event/{event}/sponsors/get-sponsor', 'Api\EventDayController@show');
        Route::get('/event/{event}/{agendaType}/get-days/', 'Api\EventDayController@getAgendaDays');
        Route::post('/event/{event}/{agendaType}/{eventDay}/{session}/add-to-my-agenda', 'Api\EventAttendeeSessionController@addToAgenda');
        Route::get('/event/{event}/{eventDay}/get-event-agenda-categories', 'Api\EventCategoryController@getEventAgendaCategories');
        Route::get('/event/{event}/{agendaType}/{eventDay}/get-sessions/', 'Api\EventDaySessionController@getDaySessions');
    });

Under the web middleware but then technically putting this in the web file it's not api?
RahulDey12 commented 4 years ago

@jamesh-purr have you added EnsureFrontendRequestsAreStateful on api middleware

jamesh-purr commented 4 years ago

@jamesh-purr have you added EnsureFrontendRequestsAreStateful on api middleware

I have indeed. I have exhausted all options. I have tried every bit in the documentation and other sites.

ShinHyungJune commented 4 years ago

I have a problem with subdomain too T.T

stankovicmilutin commented 4 years ago

Then you have to use web middleware

This means, use routes/web.php not routes/api.php

ShinHyungJune commented 4 years ago

i solved my problem. i have two site(1. vrawer.com, 2.dev.vrawer.com)

  1. .env(vrawer.com) SESSION_DOMAIN=.vrawer.com SANCTUM_STATEFUL_DOMAINS=vrawer.com

  2. .env(dev.vrawer.com) SESSION_DOMAIN=.vrawer.com SANCTUM_STATEFUL_DOMAINS=lunch.vrawer.com

Important thing is before you test login, clear cookie and session first 1

RahulDey12 commented 4 years ago

@ShinHyungJune you can just use it like *.vrawer.com

AmirrezaNasiri commented 4 years ago

@ShinHyungJune Aaaah cookies! As Adam Wathan said:

The most important debugging step I so often see people missing is validating every single assumption you have about the code. Don’t focus on what might be broken, start by proving that everything you think is working is actually working. 95% of the time the bug is there.

jamesh-purr commented 4 years ago

I did manage to get this working with another project. I just think the documentation isn't very clear and is a little confusing. So even though this works with the web cookies you can't use the standard laravel auth login pages/views that are generated. You need to do an ajax call instead first to the sanctum api route and then call the login route. I used axios/vuejs but you could use jquery if you wanted too.

tsangaris commented 4 years ago

I did manage to get this working with another project. I just think the documentation isn't very clear and is a little confusing. So even though this works with the web cookies you can't use the standard laravel auth login pages/views that are generated. You need to do an ajax call instead first to the sanctum api route and then call the login route. I used axios/vuejs but you could use jquery if you wanted too.

Still struggling with this too. Could you please share how you solved it? Thanks in advance!

epikoder commented 4 years ago

Having this issue also I'm using Vue not ui.. seems the problem is with the api middleware. i can make request to api/csrf-cookie . When I try to access my routes in api.php it gives the Access-control-allow-origin error.. What I did Create new middleware cors Replace the return statement to return $next($request)->header('Access-Control-Allow-Origin', 'yourdomain.com'); Add the class to \App\Http\Kernel.php under api for global. Or add to routeMiddleware and use middleware where needed Note.. this is on laravel 8.. laravel-cors package doesn't seem to work with wildcard either to subdomain .. I've tried it

What I noticed.. I need laravel-cors to get csrf-cookie as a custom middleware won't affect the route.

For now I can't get cookie to work as browser is refusing to set the cookies domain attribute something, but is sent as response header

epikoder commented 4 years ago

For laravel to authenticate the request.. the cookie must be present

epikoder commented 4 years ago

Having this issue also I'm using Vue not ui.. seems the problem is with the api middleware. i can make request to api/csrf-cookie . When I try to access my routes in api.php it gives the Access-control-allow-origin error.. What I did Create new middleware cors Replace the return statement to return $next($request)->header('Access-Control-Allow-Origin', 'yourdomain.com'); Add the class to \App\Http\Kernel.php under api for global. Or add to routeMiddleware and use middleware where needed Note.. this is on laravel 8.. laravel-cors package doesn't seem to work with wildcard either to subdomain .. I've tried it

What I noticed.. I need laravel-cors to get csrf-cookie as a custom middleware won't affect the route.

For now I can't get cookie to work as browser is refusing to set the cookies domain attribute something, but is sent as response header

Using url localhost doesn't set-cookie . Change to something else example.com and it's working.. just in case may be helpful to someone

jamesh-purr commented 4 years ago

I did manage to get this working with another project. I just think the documentation isn't very clear and is a little confusing. So even though this works with the web cookies you can't use the standard laravel auth login pages/views that are generated. You need to do an ajax call instead first to the sanctum api route and then call the login route. I used axios/vuejs but you could use jquery if you wanted too.

Still struggling with this too. Could you please share how you solved it? Thanks in advance!

There really isn't much more I can say to add to this. You need to do an ajax call to the sanctum api route first. Then do a post request to login route that built into laravel and then that in that order will create the session needed to begin calling your apis.

apuatcfbd commented 3 years ago

I've following setup & ITS WORKNG: API : api.some-domain.com (sub domain) Front end (react+axios) : some-domain.com (main domain)

Env file

SESSION_DOMAIN=.some-domain.com
SANCTUM_STATEFUL_DOMAINS=localhost,localhost:3000,some-domain.com

Hope that this might help someone

gopalkohli commented 3 years ago

Below is our working config.

front end https://civ4.domain.com/ backend https://secure.domain.com/

SESSION_DOMAIN=.domain.com SANCTUM_STATEFUL_DOMAINS=secure.clikodoc.com

localpath commented 3 years ago

We have dynamic subdomain

SESSION_DOMAIN=.thedomain.com
SANCTUM_STATEFUL_DOMAINS=*.sub1.thedomain.com,sub1.thedomain.com
rakibhoossain commented 2 years ago

I've one subdomain for laravel application 1) api.domain.com another one for nuxt ssr application 2) app.domain.com

Working env setup:

APP_URL=http://api.domain.com
FRONTEND_URL=http://app.domain.com

SESSION_DOMAIN=.domain.com
SANCTUM_STATEFUL_DOMAINS=domain.com,app.domain.com
afrazahmmad commented 2 years ago

I have APP_URL=https://atlanten-api.renesistechdemo.com FRONTEND_URL=https://atlanten-io.renesistechdemo.com

SESSION_DOMAIN=.renesistechdemo.com SANCTUM_STATEFUL_DOMAINS=renesistechdemo.com,atlanten-io.renesistechdemo.com

Also tried, SANCTUM_STATEFUL_DOMAINS=renesistechdemo.com,atlanten-api.renesistechdemo.com

But its still not working

alexela8882 commented 1 year ago

I have APP_URL=https://atlanten-api.renesistechdemo.com FRONTEND_URL=https://atlanten-io.renesistechdemo.com

SESSION_DOMAIN=.renesistechdemo.com SANCTUM_STATEFUL_DOMAINS=renesistechdemo.com,atlanten-io.renesistechdemo.com

Also tried, SANCTUM_STATEFUL_DOMAINS=renesistechdemo.com,atlanten-api.renesistechdemo.com

But its still not working

Hi. Do you manage to solve this thing? I already posted this on stackoverflow but unfortunately got no answers.

rakibhoossain commented 1 year ago

SANCTUM_STATEFUL_DOMAINS=renesistechdemo.com,atlanten-io.renesistechdemo.com You may try it!

SuperStar518 commented 1 year ago
I have 
APP_URL=https://test-xyz.net
CLIENT_APP_URL=https://grabook.net

SESSION_DOMAIN=.grabook.net
SANCTUM_STATEFUL_DOMAINS=grabook.net,test-xyz.net

But its still not working.

Hi. Do you manage to solve this thing?

localpath commented 1 year ago
I have 
APP_URL=https://test-xyz.net
CLIENT_APP_URL=https://grabook.net

SESSION_DOMAIN=.grabook.net
SANCTUM_STATEFUL_DOMAINS=grabook.net,test-xyz.net

But its still not working.

Hi. Do you manage to solve this thing?

@SuperStar518 you cannot use a different TLD. Sanctum is designed for stateful domain using the same TLD. The stateless auth method uses the private access token ie Mobile devices or access from a different domain entirely.

TomasKostadinov commented 4 months ago

@rakibhoossain s Solution worked for me only after changing http to https, as CORS Origins need to include the correct protocol.

APP_URL=https://api.domain.com/
FRONTEND_URL=https://app.domain.com/

SESSION_DOMAIN=.domain.com
SANCTUM_STATEFUL_DOMAINS=domain.com,app.domain.com
Yiin commented 4 days ago

I fixed it by changing SESSION_DRIVER=database to SESSION_DRIVER=cookie, for whatever reason database driver just refused to work.