jsonGPPD
jsonGPPD

Reputation: 1037

Storing Jwt Token in Cookie with Http and Secure instead of LocalStorage in Javascript

Good day guys,

I'm working on a project that has Web API (RestAPI) and SPA(Single Page Application) solutions.

Based on the video that I was following on Udemy, he stored the jwt token in the localstorage but late I found out the storing in localstorage is a bit risky since the attacker can copy the actual token and make a request in the future.

I've read some blogs that storing token in the cookie is fine since you can set the cookie as httpOnly and secure. But the problem is, I don't know how to implement it.

Here's my sample code when the user has a valid login:

axios.post('api/login/', this.account).then(response=>{
    if(response){
        localStorage.setItem('token', response.data.token); // will successfully save to localstorage
        // navigation here
    }
}).catch(error=> console.log(error); );

How can I store this in cookie with secure settings?

Upvotes: 3

Views: 10148

Answers (3)

Ben
Ben

Reputation: 16641

I've read some blogs that storing token in the cookie is fine since you can set the cookie as httpOnly and secure. But the problem is, I don't know how to implement it.

You need to implement this on the server, not on the client.

Here is an example of the server code for a login endpoint:

// If the passwords match, generate a new jwt for this user
const token = user.generateAuthToken();

// Set the options for the cookie
let cookieOptions = {
    // Delete the cookie after 90 days
    expires: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000 ),
    // Set the cookie's HttpOnly flag to ensure the cookie is 
    // not accessible through JS, making it immune to XSS attacks  
    httpOnly: true,
};
// In production, set the cookie's Secure flag 
// to ensure the cookie is only sent over HTTPS
if( process.env.NODE_ENV === 'production') {
    cookieOptions.secure = true;
}

// Send a success response to the client
// including the jwt in a cookie
return res
    .cookie('jwt', token, cookieOptions)
    .status(200)
    .json({
        msg: 'Successfully logged in',
    });
}

Upvotes: 1

Sollymanul Islam
Sollymanul Islam

Reputation: 233

You can't set a HttpOnly cookie from client end code (like Javascript). As such cookies are meant not to be read using Javascript. You have to set such cookies from the server. You can send a cookie with the response of the server and browser will store them reading from the headers. After that browser will send that cookie to the server with every request send to the server untill the cookie expires.

You can set cookie from server as following..

Cookie cookie = new Cookie(name, value); //name and value of the cookie
cookie.setMaxAge(expire); //expire could be 60 (seconds)
cookie.setHttpOnly(true);
cookie.setPath("/");
response.addCookie(cookie);

Upvotes: 3

uautkarsh
uautkarsh

Reputation: 502

This looks similar to: Set a cookie to HttpOnly via Javascript

To add to the answer this source quotes:

To prevent cross-site scripting (XSS) attacks, HttpOnly cookies are inaccessible to JavaScript's Document.cookie API

In order to save the tokens using the httpOnly and secure flags, the server will have to response with this in the header (again taken from the above source):

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly

So, I don't think that you can save the cookies securely if the server is not responding with Set-Cookie header, and is rather returning the token as a response body.

Upvotes: 0

Related Questions