In the previous section, I had explained how the web token is sent to the client using cookies. I also explained how those cookies need to be configured. In this section, I will explain how to pass the web token we received from the server to other microservices for authentication.
We saw that our web token that we set in the cookie is transferred back to the client. The important thing here is to remember that the Path
variable that we set in our cookie is what tells the browser to send the token automatically to other API calls we will make from the same client. Since we have set the Path as ‘/
‘, the browser will send our token (cookie) to every call that we make as long as our base URL remains the same.
For example, if my API call is to http://localhost:8080/auth/login
and on successful login, I send the cookie with Path ‘/
‘… it means that the browser will send the cookie automatically to other call on http://localhost (regardless of the path). This means that I can now call http://locatlhost:8081/customer/list
and my browser will send the web token (cookie) along with this request to the above API.
On receiving this request, you can now read the web token value from the cookie. Here’s the code on another server:
1 2 3 4 5 6 7 |
procedure TCustomerController.AnotherCall; var S: string; begin S := Context.Request.Cookie('authtoken'); // <-- read the token untTokenHelper.GetDataFromToken(S, 'MySecretKeyForHashing'); // explained shortly end; |
You can see the web request sending the web token automatically to the call to the new service (thanks to setting the Path
variable to ‘/
‘)
And you can see it come to the server’s API call here…
But reading the web token is not enough. Before you believe the session information this web token contains, its important to authenticate that this web token indeed has been generated by the trusted auth service and none other. We then make a call to GetDataFromToken
to authenticate the token.
The above method performs a 2-step process:
- Generate a new hash from the encoded session data from the token using the same key as the auth server did.
- Compare the newly generated hash string with the hash string in the web token.
This is where we add the GetDataFromToken
method to our untTokenHelper unit like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
function GetDataFromToken(Token: string; TheKey: string): string; var EncodedData : string; EncodedDataHash : string; CheckDataHash : string; CustomEncoder : TBase64Encoding; begin EncodedData := Copy(Token, 1, Pos('.', Token) - 1); // <-- separate only the encoded data EncodedData := StringReplace(EncodedData, '%3D', '=', [rfReplaceAll]); // <-- required for '=' chars EncodedDataHash := Copy(Token, Pos('.', Token) + 1, Length(Token)- (Pos('.', Token))); <-- separate only the hashed string CheckDataHash := THashSHA2.GetHMAC(EncodedData, TheKey); // <-- hash the encoded data with secret key (like how the auth server had done it) if CheckDataHash <> EncodedDataHash then // <-- if the newly hashed string does not match the one in the token, we know this is not token from our auth server Result := 'Invalid token' else begin CustomEncoder := TBase64Encoding.Create(0); // <-- prepare for decoding Result := CustomEncoder.Decode(EncodedData); // <-- if it matches, decode the data and send back the info CustomEncoder.Free; end; end; |
The code is explained libe by line above so no further explanation is needed.
So, that’s it! You now have your own custom web token implementation!
Here’s the complete source code of the sample services created: https://github.com/nkaku/WebToken.git