Handle the Token ID Callback

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

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

Parsing the Callback

The callback is essentially the TPP's base callback URL (specified with setredirectUrl in the token request), combined with a request-id, the signature, a status, and a tokenId 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, state, and tokenId to produce a decrypted tokenId and state.

Used to validate that each token request is initiated and completed by the same user session to protect against any potential CSRFClosedCross-site request forgery, also known as XSRF, Sea Surf or Session Riding – is an attack vector that tricks a web browser into executing an unwanted action in an application to which a user is logged in. CSRFs are typically conducted using malicious social engineering, such as an email or link that tricks the victim into sending a forged request to a server. As the unsuspecting user is authenticated by their application at the time of the attack, it’s impossible to distinguish a legitimate request from a forged one. Token guards against this type of attack by checking each request against the session ID. 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 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 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 state value parsed from the callback is the callBackState specified in the access token request (see Fields in an Access Token Request for CAF). 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.

Consequently, 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 state and token ID from callback

TokenRequestCallback callback = tokenClient.parseTokenRequestCallbackUrlBlocking(

    callbackUrl,

    csrfToken);

 

// respond to script.js with JSON

return String.format(

    "Funds sufficient to cover a charge of %s %s: <b>%s<b/>",

    AMOUNT,

    CURRENCY,

    confirmFunds(callback.getTokenId()));

Tip: Refer to script.js for an example of script code.

From a pop-up, your server-side listener may receive an HTTP POST request in JSONClosedJavaScript Object Notation – a lightweight format for storing and transporting data, often when data is sent from a server to a web page. 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 state and token ID from callback

TokenRequestCallback callback = tokenClient.parseTokenRequestCallbackParamsBlocking(

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

    csrfToken);

 

// respond to script.js with JSON

return String.format(

    "Funds sufficient to cover a charge of %s %s: <b>%s<b/>",

    AMOUNT,

    CURRENCY,

    confirmFunds(callback.getTokenId()));

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