Consents
This guide demonstrates how to create a Consent and let a user authorise it for use against the Account Information Service. A Consent is an object that holds information about what permissions a user has given you to get its account information from a particular bank.
Step 1 shows how to create a Consent. Step 2 and 3 shows how to start an authorisation process for that Consent. Step 1-3 are to be executed consecutively without the need for any user input, as such, it can be executed in the same method in your implementation. Step 4 describes how to handle the two different SCA flows.
Prerequisites
For requests to the Consent API, we need an access token for scope
"accountinformation private"
.
Variables and constants used in the guide
Name | Description |
---|---|
accessToken | An access token with scope "accountinformation private" . |
TOKEN_URL | The token URL. For production, use https://auth.openbankingplatform.com/connect/token |
bic | Will contain the BIC of the bank that you want to create a Consent for. |
CLIENT_ID | The Client ID of the application you created in the Developer Portal. |
CLIENT_SECRET | The secret that was generated when you created an application. If you did not save that value, you need to generate a new secret. |
psuUserAgent | The User-Agent from the user's request. |
psuIpAddress | The user's IP address |
xRequestID | Most requests require the header X-Request-ID , which is a uuid. This will be a unique identifier of your request and will be useful in case you need support. Make sure to create a new GUID for every individual request. In this guide, we assume that you store this value in the variable xRequestID . |
1. Create Consent
Endpoint
POST /psd2/consent/v1/consents
Request headers
Accept: "application/json",
Authorization: "Bearer " + accessToken,
Content-Type: "application/json",
X-BicFi: bic,
X-Request-ID: xRequestID,
PSU-IP-Address: psuIpAddress,
PSU-User-Agent: psuUserAgent,
Request body
{
access: {},
combinedServiceIndicator: false,
frequencyPerDay: 4,
recurringIndicator: true,
validUntil: "2021-04-23",
}
You can read more about the specific body parameters in the API documentation.
Result
consentID = response.body.consentId;
2. Start Consent Authorisation Process
Next step is to start an authorisation process for this Consent.
Endpoint
POST /psd2/consent/v1/consents/{consentID}/authorisations
Request headers
Accept: "application/json",
Authorization: "Bearer " + accessToken,
Content-Type: "application/json",
PSU-IP-Address: psuIpAddress,
X-BicFi: bic,
X-Request-ID: xRequestID,
Result
// Contains the id that represents at least one of Mobilt BankID (mbid), Mobile BankID on this device (mbid_same_device),
// Mobile BankID on another device (mbid_animated_qr_image).
authenticationMethodID = response.body.scaMethods[0].authenticationMethodId;
// Resource identification of the related SCA,
// will be used in the final step of the Redirect flow.
consentAuthorisationID = response.body.authorisationId;
// URL that will be used in the call to Update PSU Data for Consent (next step).
resource = response.headers.location;
3. Update PSU Data for Consent
This request triggers the authentication flow.
If the ASPSP supports Animated QR, the response.body.scaMethods array will contain an element with authenticationMethodId mbid_animated_qr_image
and/or mbid_animated_qr_token
.
When multiple choices are given, always use mbid_same_device
(or mbid
if mbid_same_device
is not available) if authorisation is to be performed on the same device, and mbid_animated_qr_image
or mbid_animated_qr_token
when using different devices.
Endpoint
PUT /psd2/consent/v1/consents/{consentID}/authorisations
Request headers
Accept: "application/json",
Authorization: "Bearer " + accessToken,
Content-Type: "application/json",
PSU-IP-Address: psuIpAddress,
X-BicFi: bic,
X-Request-ID: xRequestID
Request body
{
authenticationMethodId: authenticationMethodID
}
Result
The first thing we need to check in the response is the SCA flow used by the bank (Decoupled or Redirect), which will be extracted from the response headers.
// "DECOUPLED" or "REDIRECT"
scaFlow = response.headers.aspsp-sca-approach;
We are interested in different values from the response depending on if we got Decoupled or Redirect.
If the SCA flow is Decoupled, and you chose mbid
in the previous step, you need to get the autoStartToken
.
autoStartToken = response.body.challengeData.data[0]
You can the construct the full QR code like this:
bankIdLink = "https://app.bankid.com/?autostarttoken=" + autoStartToken + "&redirect=null"
If your users only uses desktops, the above is enough. You will display the QR code in the browser and poll the status of the consent authorisation to see when it's finalised.
Make sure to re-render the image if the autoStartToken
changes.
Use the bankIdLink
to ask the user to open the link on its mobile device,
you'll need to adjust the bankIdLink
slightly if you want to support users on a smartphone. If you want the user to return to your website after using Mobilt BankID, redirectUriAfterDecoupledAuthentication
should point to where you want the user to be redirect to.
If you have an application, redirectUriAfterDecoupledAuthentication
should be set to null
, this will open the previously opened application once the Mobilt BankID session is done.
bankIdLink = "https://app.bankid.com/?autostarttoken=" + autoStartToken + "&redirect=" + redirectUriAfterDecoupledAuthentication
If the SCA flow is Decoupled, and you chose mbid_same_device
, generate the bankIdLink
in the same way as outlined for mbid
and open the link.
If the SCA flow is Decoupled, and you chose mbid_animated_qr_image
, you'll need to display the B64 encoded image animatedQRImage
and instruct the user to scan it within the Mobilt BankID application.
The image is only valid for 1 second, and must be refreshed by calling Get Consent Authorisation SCA Status repeatedly at least every second but no more often than every 500ms.
// Example value: "data:image/png;base64, + B64"
animatedQRImage = response.body.challengeData.image
If the SCA flow is Decoupled, and you chose mbid_animated_qr_token
, you'll need to generate a QR image from animatedQRToken
and instruct the user to scan it within the Mobilt BankID application.
The image is only valid for 1 second, and must be refreshed by calling Get Consent Authorisation SCA Status repeatedly at least every second but no more often than every 500ms.
animatedQRToken = response.body.challengeData.data[0]
In case of Redirect flow, you need to extract the link to our auth server (which in turn will redirect to the bank's external authentication page) and replace the placeholders with the relevant values.
redirectLinkToBank = response.body._links.scaOAuth.href
Replace the following placeholders in redirectLinkToBank
in the following way:
"[CLIENT_ID]"
should be replaced by your CLIENT_ID
.
"[TPP_REDIRECT_URI]"
is the URI you want us to redirect to after we get confirmation from the bank that the user has authenticated. This URI has to be whitelisted for your application in the Developer Portal.
"[TPP_STATE]"
is a convenience field for you to put in anything you want, for example something that identifies this session. It's important that you can identify the correct session after the PSU is redirected back again.
We now have what we need to let the user authenticate. The flow will now differ completely between Decoupled and Redirect, so the instructions will be separated.
4a. Decoupled
If using desktop, you use the bankIdLink
or animatedQRToken
to generate a QR code, or the ready-made PNG QR in animatedQRImage
, that you present in your UI. Call the Get Consent Authorisation SCA Status endpoint until scaStatus
is failed
or finalised
.
If the data in response.body.challengeData.data[0]
or response.body.challengeData.image
changes, you must re-render the image displayed to the user.
Endpoint
GET /psd2/consent/v1/consents/{consentID}/authorisations/{authorisationId}
Request headers
Accept: "application/json",
Authorization: "Bearer " + accessToken,
Content-Type: "application/json",
PSU-IP-Address: psuIpAddress,
X-BicFi: bic,
X-Request-ID: xRequestID
Result
scaStatus = response.body.scaStatus;
// if mbid or mbid_same_device
autoStartToken = response.body.challengeData.data[0];
// if mbid_animated_qr_image
animatedQRImage = response.body.challengeData.image;
// if mbid_animated_qr_token
animatedQRToken = response.body.challengeData.data[0];
When the user has successfully authenticated, the status of the Consent will be valid. To know the status of the Consent, you should poll the OPE API endpoint Get Consent Status:
Endpoint
GET /psd2/consent/v1/consents/{consentID}/status
Request headers
Accept: "application/json",
Authorization: "Bearer " + accessToken,
Content-Type: "application/json",
PSU-IP-Address: psuIpAddress,
X-BicFi: bic,
X-Request-ID: xRequestID
Result
consentStatus = response.body.consentStatus
When consentStatus
== "valid"
, the Consent is ready to use for AIS calls.
4b. Redirect
First you need to route the user to redirectLinkToBank
. When the user has authenticated, the bank will route the user back to the URI you replaced "[TPP_REDIRECT_URI]"
with. Once there, you extract the URL parameters code
and scope
.
To finalise the Consent, you make the following request:
Endpoint
POST TOKEN_URL
Request headers
Content-Type: "application/x-www-form-urlencoded",
X-ConsentAuthorisationId: consentAuthorisationID, // from step 2
X-ConsentId: consentID,
Request body
{
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
code: code,
redirect_uri: redirectURI, // Will be the same value as what you replaced [TPP_REDIRECT_URI] with in the end of step 3.
scope: scope,
grant_type: "authorization_code",
}
Result
accessToken = response.data.access_token
If you receive an access token it means that the request was successful. We recommend that you also do a request to Get Consent Status like in the Decoupled flow to confirm the correct status of the Consent.