User Flows
Since oidc-provider only comes with feature-less views and interaction handlers, implementations MUST provide these components. The following describes how this module allows such customization:
When oidc-provider cannot fulfill the authorization request for any of the possible reasons (missing
user session, requested ACR not fulfilled, prompt requested, …) it will resolve the
interactions.url helper function and redirect the User-Agent to that URL. Before
doing so it will save a short-lived “interaction session” and dump its identifier into a cookie scoped to the
resolved interaction path.
This interaction session contains:
- details of the interaction that is required
- all authorization request parameters
- current end-user session account ID should there be one
- the URL to redirect the user to once interaction is finished
The authorization server expects that implementations resolve the prompt interaction and then redirect the User-Agent back with the results.
Once the required interactions are finished the implementation is expected to redirect back to the authorization endpoint, affixed by the uid of the interaction session and the interaction results stored in the interaction session object.
The authorization server instance comes with helpers that aid with getting interaction details as well as packing the results. See them used in the in-repo examples.
provider.interactionDetails(req, res)
// with expressexpressApp.get("/interaction/:uid", async (req, res) => { const details = await provider.interactionDetails(req, res); // ...});
// with koarouter.get("/interaction/:uid", async (ctx, next) => { const details = await provider.interactionDetails(ctx.req, ctx.res); // ...});provider.interactionFinished(req, res, result)
// with expressexpressApp.post('/interaction/:uid/login', async (req, res) => { return provider.interactionFinished(req, res, result); // result object below});
// with koarouter.post('/interaction/:uid', async (ctx, next) => { return provider.interactionFinished(ctx.req, ctx.res, result); // result object below});
// result should be an object with some or all the following properties{ // authentication/login prompt got resolved, omit if no authentication happened, i.e. the user // cancelled login: { accountId: string, // logged-in account id acr: string, // acr value for the authentication amr: string[], // amr values for the authentication remember: boolean, // true if authorization server should use a persistent cookie rather than a session one, defaults to true ts: number, // unix timestamp of the authentication, defaults to now() },
// consent was given by the user to the client for this session consent: { grantId: string, // the identifer of Grant object you saved during the interaction, resolved by Grant.prototype.save() },
['custom prompt name resolved']: {},}
// optionally, interactions can be primaturely exited with a an error by providing a result// object as follow:{ // an error field used as error code indicating a failure during the interaction error: 'access_denied',
// an optional description for this error error_description: 'Insufficient permissions: scope out of reach for this Account',}provider.interactionResult
Unlike provider.interactionFinished authorization request resume uri is returned instead of
immediate http redirect.
// with expressexpressApp.post("/interaction/:uid/login", async (req, res) => { const redirectTo = await provider.interactionResult(req, res, result);
res.send({ redirectTo });});
// with koarouter.post("/interaction/:uid", async (ctx, next) => { const redirectTo = await provider.interactionResult(ctx.req, ctx.res, result);
ctx.body = { redirectTo };});