I am currently working on an interaction between Angular JS app and Node.js Server (as API) with an authentication based on JSON Web Token.
But I have a question I can't answer by myself : when you encode the JWT server-side putting a user as payload, how do you proceed to retrieve the user information client-side ? Here is a small example to understand my question:
I am a basic user, I send my credentials to the API for authenticating. In exchange, I receive a JWT token but I don't have any information about the user since only the server has the secret key that is able to decode the JWT token. So does the server need to send me for example the id of the user so that I could call my api user/id for retrieving information about the user authenticated?
You have the payload on the client, If your needed data is in the payload you can easily do a Base64 Decode
on payload to find it!
To understand this here are steps:
Client send username:user,password:pass to server.
The server starts the authentication business and finds that the user name and password is valid.
The server must return these information back to client. Here is where JWT
has some rules. The server must return a token
back to client. The token has three parts Header.PayLoad.Signature
. Forget about signature right now, which is the part which make some confusion.
The part one is Header
. Some thing like:
{"typ":"JWT","alg":"HS256"}
Which will be eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
after Base64 Decode
. Please consider this is just a decode, no encryption at all! To see this you can go to https://www.base64decode.org/ and test.
After the header
, the server needs to send a payload to user. The server may decide to send below json ( I said decide, because there is no standard requirement here, you can send more or less data as payload, for example, you may also set user privileges for example admin:true
, or user first and last name, but keep in mind that the JWT size must be small as it will be send to server on each request)
{"username":"user","id":3,"iat":1465032622,"exp":1465050622}
Again according to JWT
, the server needs a Base64 Decode
here ( and again no encryption at all). The above json will be eyJ1c2VybmFtZSI6IjEiLCJpZCI6MywiaWF0IjoxNDY1MDMyNjIyLCJleHAiOjE0NjUwNTA2MjJ9
.
Until now the server created the Header
and Payload
. Now time to make signature! It is very easy:
var encodedString=base64UrlEncode(header) + "." + base64UrlEncode(payload);
//As our example base64UrlEncode(header) is eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
//and the base64UrlEncode(payload) is eyJ1c2VybmFtZSI6IjEiLCJpZCI6MywiaWF0IjoxNDY1MDMyNjIyLCJleHAiOjE0NjUwNTA2MjJ9
var signature=HMACSHA256(encodedString, 'a secret string which is kept at server');
The signature is made with a secret key which you don't have it at clent!! You don't need it either. All token data is in the payload and can be accessed with decode ( again no decrypt ! ).
This signature is used at the server, when you send token back to server, the server check that signiature is correct to make sure he can trust the token data.
To summarize have a look at below token
//Header
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.
//PayLoad
eyJ1c2VybmFtZSI6IjEiLCJpZCI6MywiaWF0IjoxNDY1MDMyNjIyLCJleHAiOjE0NjUwNTA2MjJ9.
//Signature
0K8TL1YS0XKnEIfI3lYs-bu2vbWHSNZsVJkN1mXtgWg
Header and payloads are Base64 Decoded
and you can encode it on client. But you can not do any thing with signature.
The signature is only used by the server. The client send each request with his token, the server must be sure that the client did not change any part of token payload (for example change userid). This is where the signature string come importance is revealed, the server recheck the signature with it's secret key for every request!
Note:
Do you still wonder why the JWT use encode and decode ?! To make the hole token URL safe !
The strategy in the accepted answer works, but it misses the fact that the client can see the payload of a JWT. It is explained nicely in The Anatomy of a JSON Web Token.
A JWT has 3 parts. The first two, header
and payload
, are base64 encoded. The client can decode them easily. The payload has claims about the user, the client can use this data (user id, name, roles, token expiration) w/out having to make another request to the server.
The third part of the JWT is the signature
. It is a hash of the header
, the payload
, and a secret that only the server knows. The server will validate the token and user's permissions on every request.
The client never knows the secret, it just has a token that claims to be the given user.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With