How do you log out with DRF Djoser JWT? - django-rest-framework

This is quite a simple question when I'm using JWT based authentication and there's seems to be no url that I can make a request to, if I want to logout. Is it practical to just simply clear the localStorage and refresh the page unlike token based authentication where you need to make a request to /token/logout/ ?

Related

JWT in Cookies - do I need a refresh token?

I'm implementing security for my React SPA using Spring Security on the backend. After a lot of reading, I opted for the following approach :
HTTPS everywhere
POST /login takes credentials returns JWT_TOKEN & XSRF_TOKEN in cookie form. I build the JWT_TOKEN myself whereas Spring Security handles the XSRF_TOKEN. Both cookies are Secured and SameSite=Strict. The JWT token is HttpOnly.
Subsequent API calls require the X-XSRF-TOKEN header. This is read from the aforementionned cookie. Both are sent and Spring Security compares them. JWT is automatically sent and checked in a Filter.
Every time a XSRF token is used, Spring Security generates a new one to prevent session-fixation attacks
XSS protections are applied by Spring Security
So now I'm wondering about refresh tokens. I'm reading a lot of contradictory info out there. Do I need them with this setup? If so how best to handle this ?
Many Thanks
In general, as its name says, the refresh token changes from one token to another. Typically they are used in OAuth protocol-based authentication. They are useful when an access token has expired, but the user's session is still valid.
First, JWTs are a great choice for access tokens. They have claims that match the access tokens requirements, such as: exp, iat, jti, sub, etc. But, when using a cookie-based authentication there is no need for access tokens and possibly no need for JWT.
As you said, your JWT_TOKEN is being set as an HttpOnly cookie, which means that only the server has access to it. JWT is useful for sharing the initial state between the client and server, and vice-versa. If your server is just taking it to look up the database, you don't need a JWT, you are just using a session concept, and keeping session data on a JWT may not be a good practice.
Second, if your authenticated cookie data will live at /login and die at /logout, there is no need for refresh tokens. Refresh tokens are an exchange key for short-life access tokens. Instead, your cookies keep the session live and don't need to be exchanged by something else.
For example, if the user uses the /login route to exchange your username and password for one short life access_token. He may need the refresh_token to get a new access_token without needing to send his username and password again.
If you are using the OAuth protocol or similar, refresh tokens are essential to provide a more seamless experience for your users and avoid the inconvenience of repeatedly having to re-enter their credentials. But even on OAuth, they are not mandatory.

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.

Spring Social losing auth token on redirect

I'm trying to use Spring Social Facebook login along side form login, more or less following the guide here: http://www.baeldung.com/get-user-in-spring-security, only using header-based session management rather than cookies. Right now the login is successful. Facebook sends a 302 to my server at /api/signin/facebook, and my server sends a 302 to the post-sign-in url I've set on my ProviderSignInController along with the x-auth-token header. The issue is that when following the last redirect my browser throws away the auth token.
I think I want to just add the auth token as a query param on the final redirect uri, but I don't know how to intercept the final response. I've called setSignInInterceptors on my ProviderSignInController but that seems to be ignored after the first sign in. How can I keep my session information when it's not a cookie?
Just added the token as a query parameter and returned it from my custom SignInAdapter.signIn method. I feel like there's probably a better solution but I needed something.

Spring Security - REST API - token vs. cookie

I have written a REST- API in Java and I have secured this API with Spring Security. The procedure is like this:
Frontend invokes /login RestService in Backend
Backend gives back token to frontend
at each REST- API Backend invokation the token has to be placed in header
This works fine, but I have read that it is also possible (with Node.JS/Passport.js/Express.js) that the session object with the cookie inside can be transfered out of the box without any custom code.
My question now would be if there is a better approach so that the frontend/client do not need to set the token into the header all the time for any request.
Usually token based authentication has advantages over cookie based.
You can achieve this using middle-ware layer
Here is a good Post - https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/
Server side, I usually first check in the headers if there is an auth token. If not, I then check in the cookies as a fallback.
If you want to use cookies, then at your step 2, you need to add a Set-Cookie header to the response, so that browsers know they must store a cookie. Once done, no need to add a header client-side, since browsers will send cookies each request. You'll need to add a CSRF protection though (here is a good example).

How do I handle ajax authentication after initial Login with Shiro

I have implemented the usual username/password login process with Shiro for my single page webapp which will submit the username and password over https in production. I use a REST back end rather than a typical MVC framework of any sort to facilitate my SPA. Typically with a REST API a BasicAuth is used to log in, and in response if successful an encrypted token is returned either as a cookie or a response header. Subsequent calls would return the cookie or header to avoid having to resend username and password. Usually the token is an ecnrypted username possibly with some other info that can be derived on the server side either as a session token or something else.
Anyway, as I said I am using Shiro and I understand Shiro can use multiple realms for authentication and authorization. What I am trying to do for my web site is require the initial username/password login, then after a user is logged in, somehow avoid the Shiro UsernamePassword authentication process and instead use the token check process.
I think the right way is to provide my own custom authentication realm and credentials matcher.. and I have a public domain SHA256 salted password bit of code that stores the salt, iterations and password in one string that I'd like to use. What I am not sure of is how to configure the shiro.ini... do I need to provide two custom classes, one for my own username/password for initial login, then another for my token authentication? Or can I utilize the built-in shiro usernamePassword, and will it's rememberMe feature be good enough in jquery $.ajax() calls? Perhaps I can use the Shiro implementation but also need to attach the shiro rememberMe cookie to all my $.ajax() calls?
Just a little confused really on the best approach to provide good username/password initial login and subsequent calls without needing to resent username/password... and to support session invalidation and logout functionality.
Another thought is to not use Shiro, instead use my own servlet filter to check for the initial login, if authenticated, return the response header (or cookie) myself with my own encrypted token that I keep in HttpSession or in a database back end for the duration of the session, and make sure in my jquery ajax that after each response to look for the token, and resend it in the subsequent requests.
Thanks

Resources