Closed ericwang401 closed 3 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!
I have already visited and posted my issue on the Laravel Discord, Stackoverflow, and Laracasts Forums.
I believe this is a bug because I have to use the web
middleware.
BUT I already added EnsureFrontendRequestsAreStateful
middleware to the api
middleware group in app\Http\kernel.php
(you can see this in the Github repo: https://github.com/AnushK-Fro/Stratum)
Oh ok. Could the documentation be updated to be slightly more clear?
I believed from the documentation that I could simply add the middleware to the api group and have Laravel Sanctum authorize the API routes.
Because from this tutorial (https://youtu.be/uPKd3q-iaVs) and several other Stackoverflow threads, I saw no instances of the web
middleware included.
To add onto that, the tutorial I mentioned earlier doesn't use the web middleware and explains at 1:37 that EnsureFrontendRequestsAreStateful
is similar to the web middleware group. From this, I inferred I could simply use the api
middleware without having to add the web middleware group.
The repository used in the tutorial is here: https://github.com/ggelashvili/nextjs-spa-auth-laravel-sanctum-backend/
If you open up the RouteServiceProvider
file (https://github.com/ggelashvili/nextjs-spa-auth-laravel-sanctum-backend/blob/master/app/Providers/RouteServiceProvider.php), there is no web middleware included in the API routes.
And in the api
route file (https://github.com/ggelashvili/nextjs-spa-auth-laravel-sanctum-backend/blob/master/routes/api.php), there is no web middleware included.
Finally, in the kernel
in app\Http
(https://github.com/ggelashvili/nextjs-spa-auth-laravel-sanctum-backend/blob/master/app/Http/Kernel.php), the tutorial only used EnsureFrontendRequestsAreStateful
middleware.
If I have to use the web
middleware instead of the middleware provided by Sanctum, can the documentation be updated to reflect that EnsureFrontendRequestsAreStateful
will not authorize cookies used on the API routes?
I don't want people to spend hours (or days) searching for a solution to find that EnsureFrontendRequestsAreStateful
does not authorize API routes and they have to use the web
middleware.
Thanks!
I tried this on a fresh installation of Laravel with Fortify + Sanctum, and I reproduced the same problem on my local development environment (not a VPS).
(Routes are located in routes/api.php
)
https://drive.google.com/drive/folders/10rWjrv9hOL0dfQ5U7QSKLcSVc68pHe9N?usp=sharing
Also, in the installation (link), EnsureFrontendRequestsAreStateful
was explicitly stated in the documentation to be used to authenticate SPAs.
Can this issue be reopened?
@driesvints Hey can this issue be reopened?
Thanks!
Can you post the link to the laracasts forum post of your issue?
I, unfortunately, don't have a thread created on Laracasts forum.
I was using Laracasts forum and Stackoverflow to look for solutions, and I posted the issue on Laravel's discord.
Please try the laracasts forum or laravel.io forums first.
@SynEnt I am facing some similar confusion on deciding between using routes/web.php
or routes/api.php
with sanctum and would like to know more about your issue/solution.
Did you post this somewhere else on laracasts/laravel.io where I can follow it?
@ks217 Ah, my apologies. I haven't updated this issue report and just saw your email in my inbox today! So, I found that this issue was because of my misconfiguration on Postman (not the server), and not the maintainers/developers of Sanctum.
Apparently, when I made the new request to my endpoint https://<host>/api/client/wow
, I did not include the Referer: {{ host }}
part in the headers, which triggered Sanctum to disallow the request (to prevent XSS, I presume).
So, what I did to fix my own error was to add the Referer
header in my request.
If you want to prevent this in the future, I recommend saving all your requests in a folder like this:
And adding this script (you have to set your environment variables, check my reproduction for instructions): **pm.request.headers.add({key: 'Accept', value: 'application/json' })
pm.request.headers.add({key: 'referer', value: pm.environment.get('host') })
pm.sendRequest({ url: 'https://'+ pm.environment.get('host') +'/sanctum/csrf-cookie', method: 'GET' }, function (error, response, { cookies }) { if (!error) { pm.environment.set('xsrf-token', cookies.get('XSRF-TOKEN')) } })**
Here is how you can apply it to all future requests, so you don't forget them.
Step 1:
Step 2:
Click the tab in the screenshot below and paste the code.
From now on, every request you save in that folder, it will automatically append the Accept
and referer
header to each request.
I would choose api.php
if you are creating APIs for SPA apps or REST APIs.
In fact, you can also create your own route files in the RouteServiceProvider.
You can take a look at how I am organizing my routes below: https://github.com/StratumPanel/Stratum-Panel/blob/main/app/Providers/RouteServiceProvider.php
@SynEnt Hey, Thanks for the detailed reply and sharing your code!
I had already setup Postman the same way as you mentioned. I did not face issues with that.
I will see if RouteServiceProvider
helps my case.
As of now, I have figured that
Description:
The middleware, EnsureFrontendRequestsAreStateful, is not properly authorizing the cookies in the request.
I have to use the web middleware along with api middleware in order for it to properly authorize. This is not ideal to me.
I have already added the middleware in the kernel:
I have already added the env variables (AND cleared config cache AND rebooted my VPS):
Other information:
Steps To Reproduce:
Creating a user:
php artisan tinker
Stratum\Models\User::create(['name' => 'test', 'email' => 'test@test.com', 'password' => Hash::make('password')])
Setting up Postman environment:
No Environment
https://<host>/api/login
(Replacepm.sendRequest({ url: 'https://<host>/sanctum/csrf-cookie', method: 'GET' }, function (error, response, { cookies }) { if (!error) { pm.environment.set('xsrf-token', cookies.get('XSRF-TOKEN')) } })
https://<host>/api/client/wow
for your URL (replace{ "message" : "unauthenticated." }
Workaround for this issue
app\Providers\RouteServiceProvider.php
'web'
middleware to theRoute::prefix('/api/client')
route (MAKE SURE 'web' IS FIRST IN THE ARRAY)test