Every example code describing JWT usage talks about a payload, usually this is user information like name and role.
I'm wondering what's the point of encoding that information inside the JWT when there's no additional security and only burdens the front-end making it load a library specifically to decode the JWT.
What I'm asking is if there's a reason to make this encoding instead of just sending user data (or whatever payload you need to pass) alongside with the JWT in the answer.
Currently I'm sending: (this is ExpressJs code)
const jwt = jwtUtils.buildToken(user);
res.json({ jwt });
Where jwt contains a payload with user information.
But what if I do instead:
const user = userModel.get(userId);
const jwt = jwtUtils.buildToken();
res.json({ jwt, user });
This way I don't need to decode JWT to access my user data, I would just save the JWT to be able to send it on each further request after authentication and access user data directly.
What am I missing?
Nobody forces you to put the whole user information into your token, and it is generally recommended to limit the payload of the token to a minimum.
According to RFC719 section 4.1 all claims are marked as OPTIONAL.
But one thing you're missing is that the backend usually needs to identify the user from which the incoming request was sent, e.g. to grant access to only the resources the user is allowed to access or for logging purposes etc. Also a user role is sometimes needed on backend side. Every information which you use on backend side for authorization purposes should be part of the token itself, because the signature ensures that this information was not manipulated.
So in most applications it's enough to limit the payload to just a user id and usually also the expiration timestamp.
E.g.:
{
"exp": "1516239022",
"id": 1
}
Other information, such as the user name, are often only used at the fronend and are often meaningless for the backend.
Related
I would like to ask little theoretically.
I have an angular6 + spring app that has its own client, app-specific client data.
These data can be divided into two groups
managment-data: Like client roles that allow client to visit different parts of app
client-data: personal settings, history of activities etc.
Because I would like to make login as user-friendly as possible, I would like to implement facebook login.
After user click "FB login button", facebook returns me some-user info and mainly a security token. How could I use this to securely communicate with my BE.
When someone sends request to BE, I need to be sure, that its the same person that logged in to facebook.
If I send this token as part of request, what stops possible attacker to somehow obtain token and then impersonate original user?
In what form I should send data I got from Facebook to my own server?
How should I work with token on server?
How can I validate its authenticity?
Thank you for answers
Filip Širc
You should look into the usage of OpenID Connect along with OAuth protocol. It allows you to authenticate the user to your client application (Angular6 + Spring app) to verify the user details.
When you are sending an access token to access a certain resource, you should avoid sending it as a request parameter. Usually it is encouraged to send it under the Authorization header of the request as a bearer token. However, if you want it to be extra secure, you could encode the token before sending so that it would be difficult to decode it and steal any valuable information.
Also, when you are sending sensitive information, it ise better to send them in the form of a JSON Web Token (JWT). You can use a third party library to create a jwt to include the information that need to be sent to the server. You can sign the jwt with your own signature which can be validated later. Refer https://www.rfc-editor.org/rfc/rfc7519 for detailed information about jwts.
You should use the claims in your access token to grant a user access to the resource you are protecting. Since most of the tokens are sent in the form of jwts, you can decode them and get check the necessary claims such as scopes, audience (client app), subject (user), etc.
Most importantly, you should validate the signature of the token sent from Facebook to make sure its an authentic one. For this, you have to get the public key details from Facebook's jwks endpoint and validate the signature using a third party library (auth0, nimbusds, etc.). Facebook's digital signature will be unique and this verification process is the best way to ensure the security. Also, you can check whether certain claims in the token match your expected values to validate the token. This can also be done through libraries such as ones mentioned above. Here's auth0 repo for you to get a general idea.
I want to build a REST API which will be used by both mobile app and also a website. I was wondering how would I go about implementing a simple login system for users?
For a simple website, after checking the username and password, one could set a SESSION variable and have the user "logged in".
Now, REST is stateless so I suspect that the above is not the way to go about. I thought that a possible solution would be to have the server generate and return an access token each time the user logs in, and the client will need to attach this access token to every subsequent request to access protected endpoints.
Is the above a viable solution or what is the industry standard for something like this?
(I found OAuth 2.0 to be overkill, but I could be wrong)
There are several token authentication schemes, but if you're looking for the industry standard, then JWT (JSON Web Token) is the way to go. Here's how the process usually goes:
Client sends his credentials (e.g. username and password) to the server.
The server verifies that the credentials are correct, generates a JWT and returns it to the client. Client saves the token in e.g. localStorage.
For each subsequent request, the client will attach the JWT as a part of the request (usually in the "Authorization" header).
Server will be able to decode the JWT and decide if the client should have access to the requested resource.
Now, some interesting features of JWT come from the fact that there is data encoded in it. Some of it everyone can decode, and some only the server can decode.
So, for example, you could encode the user's id and profile picture in the JWT so that the client can use the data from it, not having to do another request to the server to get his profile.
JWT has embedded info about expiration. The server can set the expiration time.
Another cool thing about JWTs is that they are invalid if changed. Imagine you stole someone's token, but it's expired. You try to change the expire information inside the token to some time in the future, and send it to the server. Server will deem that token invalid, because the contents doesn't match the signature attached, and a valid signature can only be generated by the server.
Okay, i'm developing an Angular 2 app. I've added auth0 authentication, but to me it handles sessions very insecurely. The jwt token is not encrypted and saved inside localStorage. The claims are visible for anyone, they can easily be decoded and revealed. Not to mention, Web Storage itself isn't a secure place.
I'm opting for JWTs because later i want to transform this web app to desktop app with electron and so i cannot use cookie-sessions. My users will have additional information such as roles, which i don't want to look up in db on every request, that's why i would like to store them in jwt. It makes sense to encrypt the data, but auth0 doesn't seem to provide that function.
If claims like roles are stored in localStorage unprotected, what's stopping me to go to firefox console and change the token, e.g. make myself an admin?
If claims like roles are stored in localStorage unprotected, what's stopping me to go to firefox console and change the token, e.g. make myself an admin?
Because JWT is signed, so any alteration to the content or the signature will be detected during validation
The digital signature, the third part of a JWT token like this hhhhhh.ppppppp.ssssss is created using server private key, and is the way you can verify the identity of the issuer of the token and also that it has not been altered
If you want to hide the payload, the JWT specification allows use encryption (see Json Web Encryption-JWE at RFC). If auth0 does not support it, you have a lot of libraries listed in jwt.io
JWT token has two parts: explicit (codet by base64 algorithm) - with payload data like for example exp time or user Id and role etc. and implicit - hash key which guarantee with extremely high probability that any part of explicit data was not change after token was created (by server using it's private key). So in Local/Session storage you can store this explicit part. The full token should be store in httpOnly cookies - then you will be protected against XSS attack (where hacker want to stole you token).
So you can read and change jwt token payload from firefox, but you will be unable to generate implicit hash - and server will reject your token.
So the answer to title question is: because Auth0 id_token is JWT token :)
In restful application, for some reqirements,e.g. On client side,for the same user can using only one access token at the same time and user can get new access token via login successfully.if logined twice,the user will got two different access token say it's access token A and B.In the backend,when user still use token A to talk with server, it should be invalid and the latter B should be valid!How to implement this without using cache framework or db?
Additionally in the backend, i don't want store any access token, the access token contains simple user info and timestamp etc, which is a string encrypted with aes and encoded with Base64.
Unfortunately, you won't be able to do what you want without persisting the tokens.
I answered a question related to token based authentication before. Maybe you can get some inspiration from there.
Different types of tokens
Basically, a token can be opaque (which reveals no details other than the value itself, like a random string) or can be self-contained (like JSON Web Token).
Random String: A token can be issued by generating a random string and persisting it to a database with an expiration date and with a user identifier associated to it.
JSON Web Token (JWT): Defined by the RFC 7519, it's a standard method for representing claims securely between two parties. JWT is a self-contained token and enables you to store a user identifier, an expiration date and whatever you want (but don't store passwords on it) in a payload, which is a JSON encoded as Base64. The payload can be read by the client and the integrity of the token can be easily checked by verifying its signature on the server. You won't need to persist JWT tokens if you don't need to track them. Althought, by persisting the tokens, you will have the possibility of invalidating and revoking the access of them. To find some great resources to work with JWT, have a look at http://jwt.io.
Persisting tokens
There are many databases where you can persist your tokens. Depending on your requirements, you can explore different solutions such as relational databases, key-value stores or document stores.
Just remember to remove old tokens in order to prevent your database from growing indefinitely ;-)
The access token must be send in every request in Authorization header. For every user you store his access token. So access token arrives, you check its value and find which user it is. If you do not find access token, user is not authorized.
So basically when you generate new token, you replace the old access token for given user, when old access token comes you are not able to recognize it (it is not stored anywhere), therefore it is invalided.
I need to implement an authentication scheme for a RESTful architecture. From several articles which I have read include basic Authentication using HTTPs and Session management using Cookie.
However I'm not well understanding the use of cookie. What i understands is that user first sends credentials. The server checks if the credentials are Ok. If yes, the server generates an authorization token and place it in the cookie. Onwards, on each and every request, server checks the validity of the token in the cookie.
But how does the server know that the content of the cookie is valid. Does it stores it somewhere and then it compares it??
The key point here is the authorization token. When generating one and sending back to the client, you store the auth token along with the username in let's say a database. You store the auth token in the cookie. The client on subsequent requests sends you the username and the cookie alongwith which contains the auth token. You verify this token against the supplied username and then perform the action per need.
However, do note that settings cookies makes your webservice call stateful and defeats the purpose of REST.
To achieve authentication/authorization, instead of setting the authorization token in the cookie, send it back as a response value. The client reads the value of auth token and then supplies the same in every REST request as a parameter of request body. Thus, you won't need to set cookies. This you may term as the toned down and simpler version of what is implemented in OAuth based API access.
I'm not an expert, but a good starting point to understand this is the section on Sessions in Hartl's book.
If I'm not mistaken it works as follows:
When the token is created, it uses a formula, e.g. the username and a unique user key (a salt) encrypted together. Both the username and the salt are stored in the database, and the salt is unique to that user. So, as you would do to compare if passwords match, to check the validity of the cookie you recreate the token and compare it to the one in the cookie. If it matches, then the right user is logged in and therefore authorised.
Hope this helps, or at least points you in the right direction :)