I want to store my auth token in HTTP only cookie, with version 3.4.1 this scheme worked, but after update to 4.1.0 I get strange behavior, I can authorize but after reloading page, I am not authorized any more.
So can you please add proper support for HTTP only cookie auth strategy, and add documentation for this usage scenario ?
in issue #92 ,
@breakingrobot said
Also, setting httpOnly will involve that Nuxt will not be able to modify the cookie client side, which for a static website or a SPA would be a bad idea.
which for a static website or a SPA would be a bad idea.
Why is a bad idea?
I just want to get more secure solution, and for previous version this strategy work fine, with this config
token: {
enabled: false,
localStorage: false,
cookie: false,
}
but for new version it doesn't work.
There are no reasons to not support this token storage method, just need a documentation how to use auth-module with https only cookies
By using httpOnly cookie, Nuxt won't be able to interact with it on client-side.
@pi0 we should have a discussion about cookies again asap.
If you use httpOnly cookie, it will be great on security side. BUT nuxt can't handle cookies (disabling cookie, changing cookie etc).
https://stackoverflow.com/questions/14691654/set-a-cookie-to-httponly-via-javascript
By using httpOnly cookie, Nuxt won't be able to interact with it on client-side.
Yes I know that, but it is also not necessary.
Auth module hit user endpoint, if response is 200 OK then set loggedIn to true, otherwise false, cookies will be sent automatically, access to cookies isn't required, same logic with logout.
In V3 I used such approach and it worked.
@breakingrobot approach is not wrong, is different, I understanding that it not the best option, but In my case, HttpOnly much better for security, thats all.
If you don't need this, use another approach, but auth-module can handle this storage method for those who need this.
I will start to use this module, but I agree with @sky-code about the possibility to use a HttpOnly cookie at least for the refresh_token.
Is this one also stored in a non HttpOnly cookie?
I think that it can be vulnarable to XSS attacks, am I wrong?
Did you make any progress on this @sky-code ? I'm currently trying to achieve the same goal.
@NetBzz No, I have switched off HttpOnly for now
@breakingrobot Storing the tokens in a httpOnly cookie does not break anything, it's just another approach. Actually, it's a lot safer approach as it mitigates XSS vulnerabilities. If you're storing secret tokens in a non-httpOnly cookie you're a very easy target. It is most certainly not a safe way to store tokens on the client-side.
Take a look at this: https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage
@sarneeh that's what i am talking about.
auth-module must have the first class support, for the httpOnly cookie auth flow and it must also have the clear instruction how to use it.
But if no have httpOnly flow, how we can protect our cookies?
I am using an approach where I split my JWT into two cookies containing signature.payload and signature. The cookie containing signature is httpOnly and signature.payload can be accessed by the browser. This way I have the safety of httpOnly cookies while getting the user info in the payload and not risking of leaking the full JWT, as they are separated.
I think this is a reasonable and should be implemented. Meanwhile I guess I will have to write a custom solution.
I'm a bit confused on the outcome of this conversation; Am I right in thinking its currently not possible to authenticate and keep session using httpOnly cookies?
@blowsie try to use https://auth.nuxtjs.org/schemes/local.html#tokenrequired tokenRequired option
Thanks @sky-code but doing this had no effect for me.
The login request work perfectly fine, sends set-cookie headers, but the next request to user does not send any cookies.
My config;
auth: {
strategies: {
local: {
endpoints: {
login: {
url: '/api/auth/login',
method: 'post',
propertyName: 'result'
},
logout: { url: '/api/auth/logout', method: 'post' },
user: { url: '/api/auth/ping', method: 'get', propertyName: 'result' }
},
tokenRequired: false
}
}
},
This authentication Rest API is working perfectly fine in other solutions of mine
This was due to my application using secure cookies but i wasnt running https 馃う鈥嶁檪 .
Thanks!
But if no have httpOnly flow, how we can protect our cookies?
Is it a good idea to encrypt the token?
@Jack74r The problem is not that the token is going to be decoded, but stolen. Encrypting the token won't give you anything in a situation of a stolen access token.
@sky-code @sarneeh OMG!!! I am in the process of migrating a vuejs SPA app to nuxt framework (SPA only and not Universal) and I just realized this issue. I really don't understand the complication here (I think I am missing something). I always listen for 401 from server responses and invalidate the local session.
@breakingrobot is there any way to extend this behavior with a plugin?
@sky-code @sarneeh @breakingrobot Sorry! I guess my problem is not relevant here.... I solved the issue with following configuration
auth: {
strategies: {
local: {
endpoints: {
login: {
url: '/login',
method: 'post',
propertyName: 'data',
withCredentials: true
},
user: {
url: '/is-logged-in',
method: 'get',
withCredentials: true
},
logout: false
},
tokenRequired: false,
tokenType: false
}
}
}
Setting the axios to 'withCredentials: true' solves my issue!
This question any progress? How to set httpOnly useapolloHelpers.onLogin ?
Setting propertyName: false for user endpoint made it work for me
auth: {
strategies: {
local: {
endpoints: {
login: { url: '/auth/login', method: 'post'},
logout: { url: '/auth/logout', method: 'post' },
user: { url: '/auth/me', method: 'post', propertyName: false }
},
tokenRequired: false,
tokenType: false
}
}
},
The new version will also provide a schema for refresh tokens. Will it be possible to set them as httpOnly cookies here? Especially refresh tokens, which are long-lived, should not be stored just like that.
I left a pretty lengthy explanation of why you should absolutely not listen to anyone telling you it's ok to set session credentials anywhere client side JavaScript can access on the original issue
https://github.com/nuxt-community/auth-module/issues/92
I've been digging into trying to get to get httpOnly to work with the module for about an hour, and come to the conclusion that maybe I shouldn't be using an auth module where the authors express ideas and opinions like those shared above ^
I am using an approach where I split my JWT into two cookies containing
signature.payloadandsignature. The cookie containingsignatureis httpOnly andsignature.payloadcan be accessed by the browser. This way I have the safety of httpOnly cookies while getting the user info in the payload and not risking of leaking the full JWT, as they are separated.
I think this is a reasonable and should be implemented. Meanwhile I guess I will have to write a custom solution.
I agree with @rur0 's approach.
Server only verifies cookie with httpOnly (signature)
In what cases it's important to use payload compared to doing request against /auth/me? Because of unnecessary api call on every route change?
I have httpOnly cookie setup in the following way:
if ($request->hasCookie('...')) {
$token = $request->cookie('...');
$request->headers->add(['Authorization' => 'Bearer ' . $token]);
}
And in my nuxt config
strategies: {
local: {
endpoints: {
user: { url: '/auth/me', method: 'post', propertyName: false }
},
tokenRequired: false,
tokenType: false
}
}
In what cases it's important to use payload compared to doing request against /auth/me? Because of unnecessary api call on every route change?
I have httpOnly cookie setup in the following way:
- When I log in, server sends back httpOnly cookie.
- When I receive a request on backend, I have a middleware that sets the Bearer token (Laravel)
if ($request->hasCookie('...')) { $token = $request->cookie('...'); $request->headers->add(['Authorization' => 'Bearer ' . $token]); }And in my nuxt config
strategies: { local: { endpoints: { user: { url: '/auth/me', method: 'post', propertyName: false } }, tokenRequired: false, tokenType: false } }
@chanar Your httpOnly cookie came from Laravel API? So that cookie will show in the API request instead of storing in the browser, In that case, that cookie will disappear when you are refreshing the browser. what you did for persisting your httpOnly cookie?
Not that we needed another opinion in here, but just to make it clear -- HTTPOnly cookies are absolutely a security best practice, it protects from many common forms of XSS attacks.
There seems to already be a PR for this:
https://github.com/nuxt-community/auth-module/pull/390
I'm going to have to move off this library but it would be nice if that PR was given a second look, I'd be willing to help work on it if the submitter is no longer responsive.
[EDIT] - I finally got around to writing a small post on how I got cookie-based auth working without nuxt-auth for now. As always thanks for all the hard work to the nuxt-auth team, will be looking to see if that PR gets looked at/merged!
Not using HTTPOnly cookies is often reported by Dynamic application security testing tools like Burp and penetration testing tools like OWASP Zed. It is important to use them and it should at least be optional to use them in this marvelous module. I think it is bad to just ignore them. Also, this issue is dating back from 2018 :(
Maybe it will be helpful https://github.com/nuxt/nuxt.js/issues/575#issuecomment-393514815
Interesting article on why this is important: https://dev.to/cotter/localstorage-vs-cookies-all-you-need-to-know-about-storing-jwt-tokens-securely-in-the-front-end-15id
I think this is a pressing problem at 2020 for an authentication module..
A potential malicious actor that had somehow managed to execute untrusted JavaScript in the web application would be able to take over other users' sessions.
At the very minimum I'd add a warning in the module's documentation and a technical explanation what's taking this long.
@chanar Your httpOnly cookie came from Laravel API? So that cookie will show in the API request instead of storing in the browser, In that case, that cookie will disappear when you are refreshing the browser. what you did for persisting your httpOnly cookie?
@harsha935 Yes from Laravel but from any backend, send the cookie with httpOnly.
Just for the update if it helps anyone. I have removed auth configuration from my nuxt config. My axios module has credentials set to true and that's it for my app.
axios: {
baseURL: process.env.API_URL,
credentials: true
}
When I login/register, I send a response with httpOnly cookie with value of token.
Whenever I refresh the page, close the tab or window I still have my cookie token included in request headers. When I need to use axios "outside" the Nuxt I use options { withCredentials: true }
Hi. A quick update on this issue:
Closing issue as cookie scheme is already supported with v5 (which is now used as main docs) and most of concerns are related to API/Frontend misconfiguration not auth module. Still we would need to improve docs to make it more bold.
Most helpful comment
I will start to use this module, but I agree with @sky-code about the possibility to use a HttpOnly cookie at least for the refresh_token.
Is this one also stored in a non HttpOnly cookie?
I think that it can be vulnarable to XSS attacks, am I wrong?