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

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.

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 Laravel middleware auth:api detect token from cookie?

I just trying to makes my auth flow more secure using a cookie on Laravel 5.7
Here my code
/**
* auth logic
*/
return response()->json(["status" => "logged in"], 200)->cookie('token', $token, $lifetime);
Then the cookie will be saved on the browser and will be used on every request.
On header with Axios
"cookie":"token={token}"
And I validate the auth using default middleware
Route::group(['middleware' => ['auth:api']])
But the auth:api did not recognize it, I can make custom middleware by manually detect the cookie, but I can't use the auth()->user() function on it.
Is there any solution for this?
From your sample code I believe your app is built on a stateless architecture where you have your JavaScript client and laravel api.
Now I am a bit confused as to why you do not want the client storing the token, if you just want to escape cross site scripting vulnerability (XSS) then you have to prepare to deal with cross site request forgery (CSRF) if you store the token in the browsers cookie.
Regarding the middleware not being able to find the token, by default the middleware is configured to lookup tokens in the request header (specifically the Authorization header) so if you decide to store it in the cookie, you have to find a way to change the token lookup in the api middleware which unfortunately I have not done before in laravel.
APIs don't generally store and send cookies. Therefore the api token authentication guard will not look for the token in a cookie. There are multiple options you can send it as though the easiest one in axios:
{
headers: {
Authorization: `Bearer ${token}`
}
}

Sanctum SPA Authentication - web.php vs api.php

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.

Laravel Vue JS JWT Implementation

I am trying to understand how an auth in a spa context with a jwt token should be implemented based on a Register / Login / Logout process. I have been searching on the web and have implemented at laravel side tymon jwt but I am confused about next step regarding register form and login form.
Do I understand well that when my user register for the first time on my website, this is at this time that the JWT token should be generated and recorded in a cookie ? If yes, is it Vue or Laravel which should record the JWT token in a cookie ? I suppose Vue ?! If yes, in which manner?
Other question: what happen if the user clear the browser cache and eliminate the cookie containing the JWT form his computer ? Does he need to register again to get a a new token ?? I am totally confused about the process.
Getting a more detailed and step by step process would help.
Thanks
The rough sketch for a JWT authentication works like this:
Registration - (optional | If the user is not registered) User fills the registration form which is posted to the register route, User account is created and the api responds with 201 ( content created)
Login - User uses his credentials to login to the app. The credentials are verified and a JWT token is issued and sent back to the user.
Vue handles the JWT Token and stores the provided token into cookies ( you can use js-cookie to handle this, usually in Vuex state )
The token is used with every request sent forth to the server, server verifies the Token and then the request proceeds.
Logging out requests the server to invalidate the token and then removes the token from the cookies.
You can use laravel passport, Laravel Sanctum or tymon/Jwt for token management.

Regarding Cross site Scripting Forgery

I am working on csrf and using spring 5. Spring 5 automatically provide supports for csrf and on enabling csrf protection on the server side I am getting
403: Invalid X-CSRF token
So this means a token needs to come from frontend?
My understanding is that backend generates csrf token and sends as a response to frontend browser and then it uses this token and send it as cookies to the backend server and then backend will validate it. is my understanding is correct?
when manually generating the hidden token for csrf, How backend will know it is a valid csrf token?
Second Scenario: Suppose two users are logged in to my website and frontend is sending this token to backend then how the application will differentiate which token is for which user?
Also please explain how it works internally means we enabled csrf protection in the backend and manually generated a token on the front end then what it does behind the scenes?
consider my frontend is JS pages
Is there is any specialty of Spring 5 which take care's of sessions for each user and validate tokens automagically for each user?. I tried finding it on the official website but didn't get it anywhere
Hi Zaib the csrf token is generated from back-end as you stated, once it is generated is automatically sent to the front-end which must take care to retrieve from the model and re-post for each "POST" requests.
You can share the csrf token via different way mostly i used header or html parameter.
A token is related to a specific session so is not really important if you have a logged user or not , even not authenticated users must send the csrf token for "POST".
The csrf token is validated via a filter placed in the front of the filter chain defined by Spring security itself, if you search in the documentation there is a table showing you the position of each "default" filter enabled by Spring security. Moreover if you enable debug on Spring ( </debug> is enough in your xml configuration) you will have printed all the filters used while processing an http request.
So each time a request with "POST" method pass through that filter , it will check if in the parameters there is the csrf token or header.
I never used as cookie so it may a different case for you if specifically need that but it does not differ on how it works.
Here is the details of csrf implementation on Spring:
https://docs.spring.io/spring-security/site/docs/5.0.7.RELEASE/reference/htmlsingle/#csrf-configure
I said "POST" method but actually the token is checked for any method that is related to a change of state , you can refer to doc here:
https://docs.spring.io/spring-security/site/docs/4.2.5.RELEASE/apidocs/org/springframework/security/web/csrf/CsrfFilter.html
Hope this help clarifying a bit the usage of the csrf token.

Resources