There is Spring MVC application - the server produces HTML, the client is not SPA (i.e. this is not about API in any form).
During authentication JWT token is generated and returned to the client. During authorization the server verifies JWT token.
How to store JWT token on client side and pass it via all further requests to the server? Remember this is Spring MVC application and not SPA.
I tried to google for any examples but the only findings relate to REST authentication, that doesn't relate to this case at all.
In worst case we can perform authentication from JavaScript and store JWT token in cache/cookie. But maybe Spring MVC supports this out of the box and we need just to set some checkbox in configuration :-)
For non-SPAs, the usual approach is to store the authentication token in the server session. When the client makes a request, the appropriate session is retrieved via the JSESSIONID cookie (or the JSESSIONID is added to the URL if cookies are disabled).
I'm not sure why you can't use the approach above, but if you want to store the JWT on the client, a common approach is:
store the token in the browser's local or session storage when it's generated, e.g. window.sessionStorage.authToken = 'token_value';
add the token to each subsequent request by setting the Authorization HTTP header to the value of the token
when the user logs out, delete the token from browser storage
I can use "Set-Cookie" header with JWT token from server side. The client will interpret this header as setting a cookie automatically. In this case passing the token to every requests will be done without additional steps from client side.
Some details are described here https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage
I will use this as an accepted answer until a better option provided.
Related
Long winded but I'm using Googles Youtube v3 Data API node.js package to sign in users and view playlists and such. Currently when a user successfully logs in with googles Oauth redirect flow a route server side is called which passes in a code by url query parameters. I'm able to parse that out, generate a token with my oauth2Client and then create a signed jwt. Right now I redirect the user to a url that has the signed jwt as a url query parameter which is then parsed out browser side and stored as a token in the local storage, this is my first time using anything related to jwts and want to be certain that I am doing things in a secure way. Being such I'm not entirely sure that how I am sending the token server side to client side is the proper way and not quite sure where to start looking.
You can pass in response like res.cookie(key, value)
There are multiple way to pass token from server side to client side
1) you can pass token in your response
2) you can pass token in response header
It is not the right way. If the server is responding to an XHR request (coming from javascript), then the server can send the JWT in the body of the response. If the server is responding a regular browser request (GET or POST, but not handled by javascript), then it's easier to just put the JWT in a cookie.
I'm using JWT for user login/signup and I had a question about sending/receiving the token.
Currently, I'm storing the token as a property in a JSON Object starting in the server, then I send it to the front-end. After the client receives the object it stores the token as a cookie. Every POST request from the client to the server will have a token property in it's body, and the response from the server will have the token as a property also.
Is this okay, or should I be sending the token as a header in the requests/responses?
Using: React (+DOM), JavaScript, Express, Node.js
Storing JWT token in Cookie is good enough. You don't need to send to token in the request body or return in response.
Good practice
Store JWT in cookie with mode http-only and is-secure: true so javascript can't see this token, and only transfer the token using https security layer.
Add a custom request header in every ajax request and verify this header in backend to advoid crsf attack.
Hey guys coming back to this post to add some more information for those who are in the same situation I was.
When using fetch to send requests to your backend, make sure you add
credentials: 'same-origin'
to your fetch options object in order to send/receive cookies to/from the server.
I used cookieParser in node backend code to send/receive cookies. Make sure to at least make them http-only and include any other security options you need or want.
So I'm unsure of the practicalities of authentication on a SPA, as I try to get used to my new stack of choice.
I will be serving a Node/Express app, with all API routes on /api, and the frontend served on the root / (all routes will serve index.html, then the client-side routing will take care of the rest. So I have the backend authentication set up with the Passport library, which works well. But how does one keep the server and client sessions in sync? As well as taking care of security.
If I make a POST request to /api/login with credentials, what do I return in the response to the client? And where is the session set?
My frontend is Vue, so I assumed I would just pass the user data (if credentials are correct) to the instance and have a user object. But I'm guessing I need to store a token of some sort? (jwt?)
If someone could clear up how this client-server architecture works, that would be great.
Cheers.
Whenever user logs in with credentials you can send a JWT Auth Token and then store the token as Cookie/Local Storage.
Then send the token as Authentication Token in each request as Request Header/Data to validate the user.
Link: Here is a tutorial with NodeJS
I want to bring a doubt about JWT tokens and CSRF from the Stormpath post that explain the advantages and disadvantages of storing the JWT either in localStorage or cookies.
[...] if you are reading values out of a cookie using JS, that means you
can't set the Httponly flag on the cookie, so now any JS on your site
can read it, thus making it the exact same security-level as storing
something in localStorage.
I'm trying to understand why they recommend adding the xsrfToken to
the JWT. Doesn't storing your JWT in the cookie and then extracting it
out and placing the JWT in the HTTP header and authenticating the
request based on the HTTP header accomplish the same thing as
Angular's X-XSRF-TOKEN? No other domain could make requests on a
user's behalf if you authenticate based on the JWT in the header,
since other domains cannot extract the JWT from the cookie. I don't
understand the purpose of the xsrfToken in the JWT - perhaps its just
an additional layer of defense - meaning that attackers would have to
have a compromised script on your site and CSRF a user at the time. So
they'd have to hit you in both ways to be able to pull of an attack.
The post is linked in this answer where says:
The last thing is to ensure that you have CSRF protection on every
HTTP request to ensure that external domains initiating requests to
your site cannot function.
[...] Then, on every request into your server, ensure that your own
JavaScript code reads the cookie value and sets this in a custom
header, e.g. X-CSRF-Token and verify that value on every request in
the server. External domain clients cannot set custom headers for
requests to your domain unless the external client gets authorization
via an HTTP Options request, so any attempt at a CSRF attack (e.g. in
an IFrame, whatever) will fail for them.
Even if they could set custom headers, they couldn't access the cookie where the JWT token is stored because only JavaScript that runs on the same domain can read the cookie.
The only way they could is via XSS, but having an xsrfToken in the JWT is compromised too if exists XSS vulnerabilities because a malicious script running in the trusted client domain could access the JWT in the cookie and include a header in the request with the xsrfToken.
So the equation should be:
TLS + JWT stored in secure cookie + JWT in request header + No XSS vulnerabilities.
If the client and server are running in different domains, the server should send the JWT and the client should create the cookie with the JWT.
I think that the equation is still valid for this situation.
UPDATE: MvdD agree with me:
As the browser does not automatically add the header to your request,
it is not vulnerable to a CSRF attack
I am the author of the Stormpath Blog Post. Storing XSRF token in the JWT isn't about that it is in the JWT, it is about that it is in a cookie. The cookie should be httpOnly, so you can not read it from Javascript.
Now, I think the point that caused a little confusion is where I talk about angular. Angular sets it's only XSRF cookie as well (which is not httpOnly) to put it into the header at request time (which can only be done by javascript on same domain). These are not the same cookie.
If you think about implementing XSRF support in your application, this has been done with storing server side state and the point of storing the XSRF. Storing it in the httpOnly cookie is about being stateless with XSRF. Here, you would validate the JWT signature, get the XSRF out of the claims, and compare it to the header.
The answer to your question is so that you do not need to store state on your server.
My understanding was this:
Store JWT is an HTTPonly cookie.
In that JWT, store a hashed version of an XSRF token.
Send the client the XSRF token when they sign in so they can store it in local storage
Later when the client sends requests, the JWT is automatically sent with each request via cookies and then you also send the XSRF token via a header or query variable and on the server side, re-hash to compare to what's in the JWT on the server
Your JWT is protected from being stolen in a XSS and you're protected from XSRF. XSS could still execute on your browser but could only do damage for that session in the browser. Ultimately, You couldn't stop someone from writing a really detailed script that just ran on your browser, so conventional safeties to protect from XSS are still needed by the web developer.
I am writing a web application using client side templating. This application needs to interact with a REST Server which supports Basic Http authentication (using ssl). So, with every request that needs to be authorized, username and password are passed in Request header.
My question is where and how to store username and password so that they can be accessed client-side by javascript code.
I wouldn't store usernames and passwords on the user's system. This is a security problem.
Instead, your REST login service should send a session cookie back that includes an encrypted authorization key. That cookie will then get passed back up upon further REST calls and your REST service backend can read the cookie to validate that the user has a valid authorization token.
If you don't want to use the cookie mechanism because you have to use a different header, still consider using the auth token method and storing the auth token locally (using cookies or local storage). If you don't have control of the backend at all, and you have to pass username/password up, then I think you are stuck. Saving the password on the client's machine (in cookies or local storage or whatever) is a bad idea because it can be read in plain text. Any encryption method you use can be easily reverse engineered.