Sanctum SPA Authentication - web.php vs api.php - laravel

I am using Sanctum for SPA authentication. In several examples I have seen, people are creating auth routes (login, logout, register) in their web.php routes file as opposed to the api.php routes file. Is there a reason for this? In the documentation I do see a mention here...
You may be wondering why we suggest that you authenticate the routes
within your application's routes/web.php file using the sanctum guard.
Remember, Sanctum will first attempt to authenticate incoming requests
using Laravel's typical session authentication cookie. If that cookie
is not present then Sanctum will attempt to authenticate the request
using a token in the request's Authorization header. In addition,
authenticating all requests using Sanctum ensures that we may always
call the tokenCan method on the currently authenticated user instance
...but that is for API Token Authentication and not directly under SPA Authentication.
Is there any reason my auth routes would be better handled in web.php?

Well, in a typical Laravel application, your API routes are stateless and do not persist a session; specifically they do not have the start session middleware.
As such, cookie based authentication will not work if you put these routes in your API file.
Having these routes in your web file allows these specific routes to be wrapped in a session, allowing cookie based authentication and then falls back to using the stateless Authorization header if required.
I forget the exact words, but Taylor is quite a fan of SPAs using cookie based authentication when they're the same domain over API tokens.
But this should explain the reasoning. You are, of course, welcome to change this if you like.

Related

Laravel SPA (Vue) Authentication with cookie or token?

the more I read about Laravel Spa (Vue) authentication, the more I ask myself about the "best way" to authenticate with Sanctum.
Official Laravel documentation says:
For this feature, Sanctum does not use tokens of any kind. Instead,
Sanctum uses Laravel's built-in cookie based session authentication
services. This approach to authentication provides the benefits of
CSRF protection, session authentication, as well as protects against
leakage of the authentication credentials via XSS.
But a lot of videos on YouTube or other tutorials on the internet all using (bearer) tokens which sounds contradictory to me. I mean, just using a single token for authentication seems to be a bit unsafe to me.
Also, some of those people defined "login" and "register" routes directly into Laravels route file, instead of using Vue router.
I'm using Laravel 8, VueJS 3 and Vuex 4.
So, what do you think: Am I on the right way by using Vue routes and sanctum authentication using cookies or not? And why?
Thank you, I appreciate that.

How to protect laravel api route from outside access but allow unrestricted access if request comes from frontend?

I'm building the backend with laravel and then using Vue as front-end. Data is accessed over api calls using axios. Now I have this relatively simple task but I can't seem to find the proper solution. I want one of the routes to be easily consumable by Vue compoenents without the need to log in, however I don't want that route to be publicly available for anyone to use.
Things I have tried:
Using passport to protect my routes and then use passport's CreateFreshApiToken middleware. Protection works fine, unauthorized users are not able to access the routes, however I don't get laravel_token in my cookies and therefore I can't get access to that route if I'm not logged in.
Use passport's client credentials grant access. Works fine and the way I want it to work but doesn't really make sense because if I hardcode the client_secret - anyone can access it and then use it to access protected routes. If I make a proxy-like solution, to call a controller method, which would issue a valid token and thus not exposing client_secret to front-end but then anyone could just call that route which issues the token and it would be pointless once again.
Apparently the answer is pretty simple and I was overcomplicating things. I don't know if this is the right/elegant way to do this but basically. If you don't need your api to be accessible from other applications (which I didn't) we can just put routes in web.php instead of api.php. This will ensure that web middleware is used and so it will use the basic csrf token validation, which is totally sufficient for protection against outside requests. You can also leave the route in api.php and just use web middleware on that route. The outcome is exactly what I needed - application is getting data over a route without any need to login AND that route is not available over postman or anything else.

What is the difference from the auth, web and guard middleware in Laravel 5.8

I'm a newbie in Laravel. Can someone explain what is the difference from web, auth, and guest middleware in Laravel 5.8?
auth middleware allows only for authenticated users to access the routes and your logic behind it. For example, only auth users can create questions and give answers.
guest middleware can only be accessed by unauthenticated users. For example, login and register page.
And web middleware is a group of middleware that you commonly use in your application. Such as cookie encryption, csrf token verification, and etc.

Is csrf enough for security when posting data to server via axios?

I use Laravel for a project. It is not a vue SPA, so no route used at all. The register, login and some other form inputs and outputs are made with modals using vue. For posting the form vars axios is used. For server side authentication laravels standard auth is used. But here is no other authentication like jwt. Should I use other auth types or would csrf be enough? Are there other suggestions?
Usually for web routes csrf token is enough secure or it has been so far. And it does:
Check if the request is a reading request (HEAD, GET, OPTIONS).
If so, skip the check. Match the token from the _token input or from the headers.
Add a cookie with the token to each request.
If you are using api routes then you can chose from Laravel passport which you can setup oAuth2 or you could build your own custom auth middleware using jwt tokens.

Getting user in API routes?

Inside my API routes, Auth::user() does not return anything.
I've read that this is because API's are stateless. And I should use Passport.
Could anyone explain why this is and if there is any way to get the Auth user in the API without using passport (or similar)?
The API routes use the auth:api guard, and do not use web middleware, which means there are no sessions attached to it. Passport is there to bridge the gap between a user and the API by using token based authentication. If you want your API to use sessions, simply give it auth instead of auth:api middleware
You can use jwt-auth which uses token based authentication. It provides an 'jwt.auth' middleware through which you can access Auth::user() without session over an api.

Resources