Version: v1.6

Implementing the Consent Endpoint & UI

note

Please read the Consent Flow Documentation first!

In this document, you will learn how to implement the Consent Endpoint using our ORY Hydra SDKs. The goal for this document is to have document this for multiple programming languages. If you are an expert in one of these languages, your help is highly appreciated in improving these docs!

Implementing the Consent HTML Form

note

The Consent HTML Form cannot be a Signle Page App (Client-side browser application) or a Mobile App! It has to be a server-side application with access to ORY Hydra's Admin Endpoint!

Accepting the Consent Request

note

Check out our reference implementation of this endpoint!

hydraAdmin
.acceptConsentRequest(challenge, {
// We can grant all scopes that have been requested - hydra already checked for us that no additional scopes
// are requested accidentally.
grantScope: ['email', 'openid'],
// The session allows us to set session data for id and access tokens
session: {
// This data will be available when introspecting the token. Try to avoid sensitive information here,
// unless you limit who can introspect tokens.
access_token: {
// foo: 'bar'
},
// This data will be available in the ID token.
id_token: {
// baz: 'bar'
}
},
// This tells hydra to remember this consent request and allow the same client to request the same
// scopes from the same user, without showing the UI, in the future.
remember: true,
// When this "remember" sesion expires, in seconds. Set this to 0 so it will never expire.
rememberFor: 3600
})
.then(({ body }) => {
// All we need to do now is to redirect the user back to hydra!
res.redirect(String(body.redirectTo))
})
// This will handle any error that happens when making HTTP calls to hydra
// .catch(next);

Rejecting the Consent Request

note

Check out our reference implementation of this endpoint!

hydraAdmin
.rejectConsentRequest(challenge, {
error: 'access_denied',
errorDescription: 'The resource owner denied the request'
})
.then(({ body }) => {
// All we need to do now is to redirect the browser back to hydra!
res.redirect(String(body.redirectTo))
})
// This will handle any error that happens when making HTTP calls to hydra
// .catch(next);

Complete Enpdoint

note

Check out our reference implementation of this endpoint!

routes/consent.ts
// This is the endpoint the user ends up at once she/he inserts their password and username and hits "Log in".
router.post('/consent', csrfProtection, (req, res, next) => {
// The challenge is now a hidden input field, so let's take it from the request body instead
const challenge = req.body.challenge;
// Let's see if the user decided to accept or reject the consent request..
if (req.body.submit !== 'Allow access') {
// Looks like the consent request was denied by the user
return hydraAdmin.rejectConsentRequest(challenge, {
error: 'access_denied',
errorDescription: 'The resource owner denied the request'
}).then(({body}) => {
// All we need to do now is to redirect the browser back to hydra!
res.redirect(String(body.redirectTo));
})
// This will handle any error that happens when making HTTP calls to hydra
.catch(next);
}
// Helps with form arrays
let grantScope = req.body.grant_scope
if (!Array.isArray(grantScope)) {
grantScope = [grantScope]
}
// The session allows us to set session data for id and access tokens
let session = {
// This data will be available when introspecting the token. Try to avoid sensitive information here,
// unless you limit who can introspect tokens.
accessToken: {
foo: 'bar'
},
// This data will be available in the ID token.
idToken: {
// baz: 'bar'
},
}
// Here is also the place to add data to the ID or access token. For example,
// if the scope 'profile' is added, add the family and given name to the ID Token claims:
if (grantScope.indexOf('profile')) {
session.idToken.family_name = 'Doe'
session.idToken.given_name = 'John'
}
// Let's fetch the consent request again to be able to set `grantAccessTokenAudience` properly.
hydraAdmin.getConsentRequest(challenge)
// This will be called if the HTTP request was successful
.then(({body}) => {
return hydraAdmin.acceptConsentRequest(challenge, {
// We can grant all scopes that have been requested - hydra already checked for us that no additional scopes
// are requested accidentally.
grantScope: grantScope,
// The session allows us to set session data for id and access tokens
session: session,
// ORY Hydra checks if requested audiences are allowed by the client, so we can simply echo this.
grantAccessTokenAudience: body.`requestedAccessTokenAudience`,
// This tells hydra to remember this consent request and allow the same client to request the same
// scopes from the same user, without showing the UI, in the future.
remember: Boolean(req.body.remember),
// When this "remember" sesion expires, in seconds. Set this to 0 so it will never expire.
rememberFor: 3600,
}).then(({body}) => {
// All we need to do now is to redirect the user back to hydra!
res.redirect(String(body.redirectTo));
})
})
// This will handle any error that happens when making HTTP calls to hydra
.catch(next);
});
Last updated on by aeneasr