9 ms·
Ask HN: Cookies vs. JWT vs. OAuth
I’m using passport.js with a local strategy for authentication, and I’m using sessions/cookies for keeping state and keeping the user logged in.
I’m not very knowledgeable in security (that’s why I’m asking here), but will using JWT (with the token stored in the cookie) to keep the user logged in instead of sessions/cookies make my application more secure when the passport middleware executes req.isAuthenticated? I thiiink somewhere in that call it checks cookies or jwt, depending on implementation.
Also, I do not plan on opening the API to other sites, so OAuth is unnecessary. Is my understanding correct?
- borplk 9y agoCookies have some excellent security features ("secure" flag, "http" flag to prevent javascript from acesssing it, and "same-site" flag for CSRF prevention on modern browsers). Don't use other storage mechanisms for storing anything secret. Nothing beats cookies today.
- ukulele 9y agoThis is such a vaguely worded question and spec that I doubt you'll get anything out of it. All three are fine in the right context and not even mutually exclusive. Maybe do some basic research first, then ask with more details on your setup and what is important vs not important.
- amend 9y agoI just updated my question, as it was vague. I’d appreciate your input!
- evfanknitram 9y agoCookies are a mechanism to store data in the client. Jwt token will still need to be stored somewhere (for example in a cookie). To me, saying Cookies vs JWT doesn't really make any sense. It's like asking what is more secure, JSON or MySql?
- amend 9y agoI just updated my question, as it was vague. I’d appreciate your input!
- makkesk8 9y agoJWT's are stateless and cookies are not, you can achieve the same thing with cookies as with JWT if you store your sessions in redis etc.. for api's I'd recommend JWT's.
- amend 9y agoI just updated my question, as it was vague. I’d appreciate your input!
- JepZ 9y agoFirst of all, that question is kinda weird as those three are not of equal type. For example, OAuth uses JWT and JWTs can be stored in cookies, but as far as I know they aren't normally. The differences between classic a session ID in a cookie vs. JWT is more or less, that JWTs often hold encrypted session information (stored on the client), while the session ID is just a random identifier and the session data is stored on some server (so its easier to build scaleable solutions with JWT). Security wise you might be interested, that cookies are sent automatically while JWTs are not (unless they are saved within a cookie). You might wanna read: https://stackoverflow.com/questions/37582444/jwt-vs-cookies-for-token-based-authentication https://stackoverflow.com/questions/37582444/jwt-vs-cookies-...
- clhodapp 9y agoOAuth doesn't specifically call for JWTs. From OAuth's point of view, all of the tokens, codes, IDs, and secrets are opaque character strings.
- kevlened 9y agoJust to be clear, JWTs may be encrypted (JWE), but are almost always just signed (JWS). Don't store data you don't mind exposing in a signed JWT.
- chii 9y agosince i was looking into GDPR, a JWT token containing signed data may potentially be a source of private data (i.e., you store the username there), and therefore, have to have a way to clear it, and/or ensure that it is encrypted in transit.
- modernpacifist 9y agoTo answer as best as possible given the vagueness: Cookies: Highly compatible with most if not all browsers (and even headless tools). Lends themselves to having an expiry date and generally best when used with time sort of short-lived expiring session. JWT: Everyone tends to use these in a stateless manner which means once issued, somewhat impossible to revoke without invalidating all JWTs or having a blacklist (and we're back at stateful). Plus some implementations had issues with downgrade attacks I think it was... OAuth 1: Fine assuming you could keep clocks in sync and guarantee the secure storage of the keys/secrets. Good in that it didn't rely on HTTPS but if the secrets ever got compromised then the attacker would have free reign of that account until detected. OAuth 2: Basically a complicated way to get short lived session tokens, potentially from a 3rd party API/auth source. Relies entirely on HTTPS to keep data secure in-transit and less of an issue if the session token gets compromised since its ideally short lived (because most want it to be stateless - those who keep a valid list of tokens sometimes skip the token expiry).
- kevlened 9y agoBefore going all the way on cookies, make sure to consider whether you're creating a mobile app, as mobile apps usually don't handle cookies for you automatically. In my experience, OAuth is a bit easier in mobile. If you support cookies for browsers and OAuth for mobile, your API will have to support both authentication methods.
- lilbobbytables 9y agoWhy not tokens? They're easy and work well with an Authorization header on mobile.
- coldacid 9y agoI'd argue that they can also be implemented in a much more lightweight fashion than having to go through a whole OAuth flow just for a mobile app that hits an API that you control completely.
- iaaacdev 9y agoAs long as you protect against CSRF attacks (I do not know anything about passport.js), cookie authentication is okay provided the API is not going to be consumed by external sites.
- mnm1 9y agoNo, it won't be more secure, just less standard and possibly more difficult to work with.
- tytytytytytytyt 9y ago> but will using JWT to keep the user logged in instead of sessions/cookies You can't use JWT without cookies, or local storage (which is effectively the same here), so that makes no sense. > Also, I do not plan on opening the API to other sites, so OAuth is unnecessary. Is my understanding correct? You're still so vague that it's hard to answer. If you want to authenticate them, you can use OAuth. But no, it's not necessary to authenticate them with any one auth service...
- amend 9y agoI updated my question so it’s more clear. The update is relavent to your first point. By local storage do you mean storage on the client or server? I thought a benefit of jwt is not having to store anything on the server, is this correct?
- tytytytytytytyt 9y agoThat's not really a benefit. If it's on the server it's far more secure, unless you've messed that up, and you have less/no issues with running out of space on the server.
- elago 9y ago"Local storage" is the name of something most web browsers implement https://www.w3schools.com/html/html5_webstorage.asp https://www.w3schools.com/html/html5_webstorage.asp
- shiado 9y agoMake sure you set HttpOnly for session cookies to eliminate XSS token stealing. If you use localStorage in an SPA for tokens make sure you set up the scope such a way to minimize XSS token stealing. Not sure how the rest of your app works but make sure you use some anti-CSRF library.
- TheAceOfHearts 9y agoNo, using JWT will not make your application more secure. Continue using cookies. Don't buy into the JWT hype. You'll probably want to add a CSRF token. You're correct in stating that implementing an OAuth provider is unnecessary. I suggest reading the OWASP security guides. Start with Session Management Cheat Sheet [0], and after that Cross-Site Request Forgery (CSRF) [1]. Don't fear the cookies, all their gotchas are well documented and understood. There's lots of valid use-cases for stuff like JWT and OAuth, but I wouldn't bother with it at all until you're more comfortable with digging into the AuthN/AuthZ minefield. I'd consider understanding session management with cookies a precursor to trying to do anything fancier. [0] https://www.owasp.org/index.php/Session_Management_Cheat_Sheet https://www.owasp.org/index.php/Session_Management_Cheat_She... [1] https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF) https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(...
- welder 9y ago> understanding session management with cookies a precursor to [JWT] +1
- teach 9y agoIt's one of the social norms on HackerNews that "low-value" comments like "Love it!" and "+1" are discouraged. Although such comments are polite to the poster, they add nothing but noise for all the other readers of the thread. Instead, it seems to be preferred that you simply upvote the post without replying.
- motohagiography 9y agoIf you needed to auth users on both a mobile app across platforms, and a browser, it makes sense to store and xmit user session information in a JWS or JWE, using it as an abstraction which you can serve as a cookie to the browser, and handle consistently across apps. If you get into multifactor auth, implementing it in JWT becomes more useful. A full OAuth provider seems heavy for what you've described.
- snomad 9y agoI found this to be a great resource when groking your question recently http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/ http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-fo... Also this previous HN thread https://news.ycombinator.com/item?id=13865459 https://news.ycombinator.com/item?id=13865459
- sdfin 9y agoThis kind of question appears often here. I found the following discussion very informative: https://news.ycombinator.com/item?id=16157002 https://news.ycombinator.com/item?id=16157002 (as you can see, there are very different and conflicting opinions about what are the best practices). I'd find it very helpful if somebody can recommend a resource, like some book, course or blog post that thoroughly explains the best practices and recommended strategies about authentication for APIs, websites and mobile apps in client/server and server/server communication.
- Lazare 9y ago> I’m using sessions/cookies for keeping state and keeping the user logged in Good. Sessions are the standard for a reason, and it's currently considered best practice. And if you've got a session ID, and your clients support cookies, then sure, use cookies for storing them. > will using JWT (with the token stored in the cookie) to keep the user logged in instead of sessions/cookies make my application more secure No. Probably less secure, although if you know what you're doing you can mitigate the issues. But certainly not more secure.
- cygned 9y agoEvery time I looked at OAuth I found it overly complex for what I wanted to do. Thus, never actually implemented that, maybe I am missing something on that, though. JWT is great until you get to the point where you want to have things like token revocation. A simple session mechanism we use for our apps: - Upon sign in, generate a session token, e.g. 32 characters. Session tokens are unique and fully random, not derived from any actual data - In our scenario, a user can have multiple session at a time. We store two mappings in a Redis database; user-id=>user-object (for caching purposes, serialized JSON) and session-id=>user-id - The second mapping has an expiration time which is the session length eventually, e.g. 30 minutes - Upon every request, we take the session id from the request (header or cookie, cascadingly) and look for the session-id in Redis. If found, we prolong the time to live of that entry. From Redis, we got the user-id (because of the mapping) and thus we can retrieve the cached user object, too. So we have a meaningless token (at least externally), our backend is still stateless (at least the application itself, Redis is stateful in nature) and we don't have to reinvent any wheels for automatically terminating sessions. In addition, it's easy to cancel session on demand and build a blacklist. We wrote the handling ourselves (except for the crypto of course), because no express.js related library/middleware was flexible enough. And eventually we kind of trusted nobody.
- deleted 9y ago[deleted]
- Ninn 9y ago> JWT is great until you get to the point where you want to have things like token revocation. What a flawed argument, there are techniques that allows for session revocation, even in an async stateless jwt context, i.e. By blacklisting, which will work great, and give you some nice properties, depending on your infrastructure and design. Sadly, some appear to assume jwt is some special solution that does X right and y wrong.. but its really nothing other than a structured format in the end. But surely a lot of people do a lot of wrong stuff when deploying their stuff on top of jwt.
- kodablah 9y agoYup, this board is full of JWT hate mostly predicated on the fact that it can be done wrong. Just use a random token as a session ID. Wrap in cookie for browser users and use browser session cookie expiration. Wrap in JWT and sign an expiration date in there for API use...no other state needed, use token to look up actual valuable state on server side as necessary. Expire them server side too based on application re-login requirements to prevent reuse (or sign your cookies w/ an expiration date like you do with JWT...but I always keep session tokens and expire them on the server side too for various reasons including auditing purposes).
- jakelazaroff 9y agoDon't use JWT or local storage for storing sessions. It's pointless/potentially less secure. Just use sessions and cookies. Here are some good blog posts that explain this better than I can (the flow chart in 3 is particularly illuminating): [1] https://paragonie.com/blog/2017/03/jwt-json-web-tokens-is-bad-standard-that-everyone-should-avoid https://paragonie.com/blog/2017/03/jwt-json-web-tokens-is-ba... [2] http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/ http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-fo... [3] http://cryto.net/%7Ejoepie91/blog/2016/06/19/stop-using-jwt-for-sessions-part-2-why-your-solution-doesnt-work/ http://cryto.net/%7Ejoepie91/blog/2016/06/19/stop-using-jwt-...
- hacknat 9y agoI’ve never thought of JWT as being something you would want to use in a unified application, it tends to shine in situations where one application is the authorizing agent for another application not totally in its control (e.g. private Docker registry auth). You can set expiry fields in JWT, so revocation isn’t the concern everyone is saying it is. Also, just because a form of auth is out in the open it doesn’t mean it’s less secure (TLS, anyone?).
- imauld 9y ago> You can set expiry fields in JWT, so revocation isn’t the concern everyone is saying it is. The issue with JWT revocation is if someone has a JWT that says they are an admin and then you make them not an admin or if an admin (or any for that matter) account is breached it's difficult to remove access from the attacker. With a session you just change the password and kill the session. This can be mitigated by short expiry times but a lot of damage can be done in a short amount of time by a determined attacker.
- therealdrag0 9y agoDepends what your definition of "unified application is". If your application has many micro-services, then a single request from the outside could folk into many nested calls. JWT can benefit this by preventing each of these calls from making it's own external auth request.
- drinchev 9y agoUsing cookies with Domain option allows you to share a cookie between `api.site.com` and `www.site.com`. You can combine that with a `Authentication Bearer` for releasing a public API access.
- bozho 9y agoSome thoughts on when it's ok to use JWT https://techblog.bozho.net/using-jwt-sessions/ https://techblog.bozho.net/using-jwt-sessions/
- dwaite 9y agoThese three concepts are largely orthogonal, but pair well. Cookies are a state management system for HTTP, which is normally stateless. Rather than representing state via data embedded in the URL or requiring intelligence in the HTTP stack to represent that state in application-specific headers, Cookies allow the server to set state on a response which will be returned on subsequent requests. The browser doesn't need any special rules behind the generic cookie retention rules. Cookies can be used for any sort of state, but in this context you probably care about authentication/authorization state. Nearly every website which uses a web-based authentication flow (including OAuth and OpenID Connect) winds up using cookies to track authentication state. OAuth is a HTTP-based framework for providing delegated authorization. Rather than sharing user credentials with every piece of code which may want to access resources associated with a user, the Authorization Service handles authentication as well as user consent to let a client act on their behalf. While there are several flows to account for different application requirements, this eventually results in an access token, a usually time-limited value which represents access to just the capabilities the user consented. Facebook, Microsoft, and Google all use variants of OAuth to share user authentication as well as provide access to user information and API access to user accounts. There are challenges to OAuth interoperability, with many deployments adding additional capabilities outside the specification (such as representing user authentication). Facebook has their own extensions, while Microsoft and Google support the more standardized OpenID Connect as a interoperable profile. Since the access token is state, there is nothing forbidding it from being set as a cookie. However, anyone who can get this token can perform actions as the user (bad) as your application (from a purely selfish perspective, worse). Many server-side web applications which store access tokens will either store them in a database and reference the row in a cookie, or store them in an encrypted cookie to prevent them from being extracted and used externally. One way to store such data in an encrypted cookie is via a JWT. A JSON Web Token is a data format defined by the OAuth working group. Access tokens are really messages for the "Protected Resources" in OAuth parlance - typically API endpoints. However, the core specification did not define any format for these values, leaving them deployment-specific. JWT was an attempt to provide a good recommendation for the format, and was also designed to be leveraged by OpenID Connect (which both extend core OAuth with new functionality and provide an interoperable profile of usage). It is typical that since security is hard, formats that take security into account (such as JWT) wind up getting both overused and oversold. People want to be able to say things like "our authentication is secure because we use JWTs", but instead statements like that are usually a red flag that the system was implemented by people who did not understand the overall security requirements.
- dwaite 9y agoThere are a few benefits of using something like OAuth even if you don't plan to open your API to third parties. 1. You may decide you want to have multiple first-party clients to your API. Examples would be a web site, a native client, a command-line app. OAuth lets all of these different applications call the same API once they get a token. 2. There could be security value in segmenting the user authentication into an entirely separate app with its own database - it greatly reduces the attack surface which could be leveraged to get your user credentials to attacks against your user authentication (and likely registration) app, vs your entire website and all your APIs. 3. If you decide to open up your API in the future, you have already done a significant amount of the architectural legwork. 4. If you decide to support social logins (Facebook or Google for instance) in the future, you can do so just at your personal OAuth authorization service. Your apps don't care how they get an access token, and your APIs are still getting a local access token that they understand (rather than trying to understand Google or Facebook tokens).
- andretti1977 9y agoJWT is more a "lingua franca" token since it is not binded to a "http context", but in the end, cookies and jwt tokens or any other kind of authorization tokens are simply a way to identify a user. As i told you before JWT tokens are more loosely coupled to http request than cookies so they may be a best choice, especially if you plan to build stateless apis. The only strictly important rule is: do not store any sensitive informations on client side data structure since you can't trust the client side.
- antihero 9y ago> do not store any sensitive informations on client side data structure since you can't trust the client side Except that the tokens are cryptographically signed, so as long as you verify them, you can trust them.
- venantius 9y agoHaha, oh man I've spent a lot of time thinking about exactly this. I don't think I've got much to add that anyone else hasn't already said, but: Cookies - well known, hard to footgun yourself JWT - new, complicated to implement, easy to footgun yourself OAuth - generally only works in certain security models. You're probably still going to end up using cookies or JWTs as part of your OAuth state management anyways. Personally, I use cookies for all "apps" and I'll use JWTs when I need authn/authz in a more complicated microservice architecture where the "clients" aren't browsers.
- ithkuil 9y agoA related topic that you might find interesting: https://air.mozilla.org/macaroons-cookies-with-contextual-caveats-for-decentralized-authorization-in-the-cloud/ https://air.mozilla.org/macaroons-cookies-with-contextual-ca...
- Shoothe 9y agoI've worked with Macaroons (writing custom tools and libraries) and Macaroons are definitely more complex than JWTs. Don't be fooled with one signature algorithm, there are more things hidden under the surface (e.g.validation of a set of Macaroons requires finding cycles in a graph and symmetric decryption of data). If you really need tokens use constrained JWTs. Better: just use random strings.
- nickjj 9y agoI just use sessions, backed by cookies. I find with JWTs you end up dealing with cookies in the end, because on browsers you're definitely going to want to persist the token in a cookie so the user can have access in between requests. Also, for the apps I develop, I often need to request the current user from a persisted database, so I'm doing a DB lookup on every request no matter what. Sure, I could cache this request in Redis but even on apps that have had to do this hundreds of thousands of times a month, it never caused any performance issues reading it directly from Postgres.
- adamscybot 9y ago"because on browsers you're definitely going to want to persist the token in a cookie so the user can have access in between requests." You'd usually just use localStorage for this purpose, not cookies. For your second point, you can store the info you need in the token itself, which is then signed so it can't be tampered with. Though yeh, sometimes, you just need the latest info in the DB. Depends on the use case.
- fimdomeio 9y agoThere are situations where you can't use cookies like when developing mobile apps [0] [0] https://stackoverflow.com/questions/31139365/can-you-use-cookies-in-a-cordova-application https://stackoverflow.com/questions/31139365/can-you-use-coo... We only stoped using cookies because of that since we wanted a more universal implementation so minimal changes had to be done between a web app and a mobile app implementation. Other than that we would keep using session cookies.
- runeb 9y agoNot familiar with the framework referenced in your link, but if you are doing truly native development on iOS, the URL loading supports cookies [0] [0] https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/URLLoadingSystem/CookiesandCustomProtocols/CookiesandCustomProtocols.html#//apple_ref/doc/uid/10000165i-CH10-SW1 https://developer.apple.com/library/content/documentation/Co...
- helb 9y agoCordova wraps a web app into a native container. I've never used it, but i guess it doesn't use (or expose?) the native loading API…
- eranation 9y agoThese are three different things. Cookies: a storage mechanism. If you use simple cookies (session GUID) for authentication, you must maintain state in some persistent storage to tell if a session ID is valid or not. httpOnly, secure cookies and CSRF protection are also required. JWT: a digitally signed document containing claims about a user. Can be stored in a cookie or in localStorage or in your mobile app’s memory/temp storage. You can be stateless as the validity of the token is protected by its digital signature. Oauth: a protocol for authorization. Can embed the authorization claims in a JWT token among other ways.
- tiuPapa 9y agoIf I am implementing just a backend API, what security strategy should I follow?
- nethsix 9y agoFor your case, you do not need JWT. Stateless JWT is useful in the scenario where one server is capable of authenticating a user (through password, social login, one-time password, etc.), and a different server holds resources that the user is trying to access. The server doing the authentication will issue a stateless JWT with all the user credentials cryptographically signed, so that the user can pass the JWT to the server holding the resource to be granted access, assuming that server trusts the authentication server to perform authentication correctly. Stateless JWT is useful here because the server holding the resources can verify the credentials of the user without contacting the authentication server. Regarding OAuth, there are 2 sides to it. You can become an OAuth provider, which I reckon you are not interested to be. What you may be interested is to use OAuth to enable users of OAuth providers like Facebook, Twitter, .etc, to access your service, so that you minimize what you have to develop in terms of user management, i.e., you don't have to worry about user creation, email verification, password resets, etc., because all those have been performed by the OAuth providers. I believe passport.js allows you to use OAuth to allow OAuth providers' users to access your service. passport.js may be a backend-base solution so you have to be somewhat familiar with OAuth to get started. Alternatively take a look a https://oauth.io https://oauth.io, which has a front-end based solution; I am not saying a front-end based solution is better, but rather it's easier to understand for someone starting out. Moreover they have JS fiddles that you can instantly play around with. Check out the JS fiddle for creating a 'Login with Github' for your website here in just a couple of lines of Javascript: https://jsfiddle.net/dg9h7dse/1/ https://jsfiddle.net/dg9h7dse/1/ There is a full explanation of what the code is doing here: https://coderwall.com/p/sjbwcq/javascript-github-social-login-button-for-oauth https://coderwall.com/p/sjbwcq/javascript-github-social-logi...