Handling the Token.io ID Callback

Briefly introduced in the previous topic, correctly handling the TPP callback URL from Token.io that contains the tokenId is critical to redeeming the access token.

It starts with parsing the URL to verify its callback signature and tokenId.

Parsing the Callback

The callback is essentially the TPP's base callback URL (specified with setredirectUrl in the token request), combined with the request-id, signature, a tokenId, an tokenId, and an accessStatus returned by the bank (all added to the base redirect URL when you generated the token request URL). It looks something like this:

https://merchant-site.com/callback?request_id=rq:3UQL47opJxxYFxZgtGD4H6kUGRep:5zKtXEAq&signature={"memberId":"m:3rKtsoKaE1QUti3KCWPrcSQYvJj9:5zKtXEAq","keyId":"lgf2Mn0G4kkcXd5m","signature":"Bzh
SptPcYBlIuEzK1K7_mPDt_ws7U0rmugiHMkQh__Be7QwlZMxbv9Hto-L52nHuonGKgUnyToQJf1QGHXyMAQ"}&tokenId=tt: 4KhFVRQqcZWCjHwrm5san6fsmTeQwj8wWuEQH682hkXL:4hGGDVR3NcU7X8CUa9f&status=FAILURE_GENERIC

For it to have any meaning, however, it needs to be parsed into its constituent components to validate the cryptographic signature binding together csrfToken and tokenId to produce a decrypted request-id, signature, tokenId and status.

Used to validate that each token request is initiated and completed by the same user session to protect against any potential attack, the csrfToken is a unique string bound to the session of the user. It can be a hash of the session cookie or a string associated with the server-side user session. Token.io strongly recommends binding the csrfToken to the user's authenticated state in accordance with ITEF guidelines.

Hence, the session cookie can be safely used as the csrfToken because the Token.io SDK hashes the token before using it. However, if your application doesn't authenticate the user, you can use the SDK's Util.generateNonce() method to generate a secure random string that can serve as the csrfToken.

The callBackState specified in the access token request (see Fields in an Access Token Request), although it can contain additional application-specific information, it should not be used to authenticate the user. Authentication must be performed before initiating the token request flow, and the callback should therefore use the same authenticated session.

Thus, when your server-side listener receives a HTTP GET request at the callback URL, it needs to call the SDK's parseTokenRequestCallbackUrlBlocking() method to extract the tokenId and verify both the signature and the csrfToken. Here's how:

// retrieve CSRF token from browser cookie

String csrfToken = req.cookie(CSRF_TOKEN_KEY);

 

// check CSRF token and retrieve callback state and token ID from callback

TokenRequestCallback callback = tokenClient.parseTokenRequestCallbackUrlBlocking(

    callbackUrl,

    csrfToken);

From a pop-up, your server-side listener may receive an HTTP POST request in format. In which case, use parseTokenRequestCallbackParamsBlocking() to extract the tokenId and verify the signature and user session.

// retrieve CSRF token from browser cookie

String csrfToken = req.cookie(CSRF_TOKEN_KEY);

 

// check CSRF token and retrieve callback state and token ID from callback

TokenRequestCallback callback = tokenClient.parseTokenRequestCallbackParamsBlocking(

    data, // these are the callback params in JSON format

    csrfToken);

Now that you've extracted the tokenId, you're ready to redeem the access token.