Skip to main content

OpenID Connect userinfo endpoint

The OpenID Connect (OIDC) userinfo endpoint is a protected resource that provides information about a user when a service provider presents an access token that has been issued by your Token endpoint. The scopes in the access token specify the user attributes that are returned in the response of the userinfo endpoint. It is important to note that the openid scope must be one of the access token claims.

In this document, we explore how to call the userinfo endpoint using the Ory SDK in JavaScript, how to add custom claims to the userinfo response, and how the userinfo_signed_response_alg field works.

Calling the userinfo endpoint using Ory SDK

The Ory SDK provides a simple way to call the userinfo endpoint using JavaScript. To call the endpoint, use the following code:


import { Configuration, OidcApi } from "@ory/client"

const ory = new OidcApi(
new Configuration({
basePath: `https://${process.env.ORY_PROJECT_SLUG}.projects.oryapis.com`,
accessToken: process.env.ORY_API_KEY,
}),
)

export async function getUserInfo(accessToken: string) {
const { data } = await ory.getOidcUserInfo({
headers: { Authorization: "Bearer " + accessToken },
})
console.log(data.email)
}

In this example, we create a new instance of the Ory SDK with the basePath set to the URL of your Ory Network project. We then define an async function that calls the userinfo function with the accessToken passed as a parameter. The data contains the user attributes returned by the userinfo endpoint.

Adding custom claims to the userinfo response

Any information included in session.id_token when accepting the consent request will also be included in the response.


import { Configuration, OAuth2Api } from "@ory/client"

const ory = new OAuth2Api(
new Configuration({
basePath: `https://${process.env.ORY_PROJECT_SLUG}.projects.oryapis.com`,
accessToken: process.env.ORY_API_KEY,
}),
)

export async function acceptConsent(consentChallenge: string) {
const { data } = await ory.getOAuth2ConsentRequest({ consentChallenge })

return await ory
.acceptOAuth2ConsentRequest({
consentChallenge: consentChallenge,
acceptOAuth2ConsentRequest: {
session: {
access_token: {
some_custom_claim: "some_custom_value",
},
id_token: {
id_custom_claim: "some_value",
},
},
},
})
.then(({ data }) => data)
}

Be aware that the /userinfo endpoint is publicly available. Its contents are thus as visible as those of ID Tokens. It is therefore imperative to not expose sensitive information without user consent.

The result is a response similar to:

{
// ...
sub: "04d75756-xxxx-4xxx-9xxx-xxxxxxxxxxxx",
ext: {
id_custom_claim: "some_value",
},
// ...
}

Returning a signed JWT from the userinfo endpoint

The userinfo_signed_response_alg field specifies the algorithm that is used to sign the payload by the userinfo endpoint. If the field is empty, the userinfo endpoint returns a regular JSON response.

However, if the value is set to RS256:


import { Configuration, OAuth2Api } from "@ory/client"

const ory = new OAuth2Api(
new Configuration({
basePath: `https://${process.env.ORY_PROJECT_SLUG}.projects.oryapis.com`,
accessToken: process.env.ORY_API_KEY,
}),
)

export async function setClientLifespans(clientId: string) {
await ory.patchOAuth2Client({
id: clientId,
jsonPatch: [
{
op: "replace",
path: "/userinfo_signed_response_alg",
value: "RS256",
},
],
})
}

The userinfo endpoint returns a signed JWT with the content type of application/jwt:

HTTP/1.1 200 OK
Content-Type: application/jwt

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhbGljZSIsImVtYWlsIjoiYWxpY2V
Ad29uZGVybGFuZC5uZXQiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwibmFtZSI6IkFsaWNlIEFkYW1
zIiwiYXVkIjoiMDAwMTIzIiwiaXNzIjoiaHR0cHM6Ly97cHJvamVjdC5zbHVnfS5wcm9qZWN0cy5
vcnlhcGlzLmNvbSIsImZhbWlseV9uYW1lIjoiQWRhbXMiLCJpYXQiOjE0MTM5ODU0MDIsImdyb3V
wcyI6WyJhZG1pbiIsImF1ZGl0Il19.XvjPXI5l9msigrY03gJyJMK717J6mZrIs1yuREtCWiGlks
g4W9jgrWzYeUhIeqrCuBJv8eRf-OTyQVd0iJ1SmCFGR_YyYHvk5YonBNdq6H_qDS-cL73-ewB-AO
yNkSoEDF3mX5jgF3jz5sZkU_DuXXM9FXr__M2UH8HVX5kNMCKJiYnYMD8ImCNIrzYuGWL3XiYrBC
_vhE8xw4f1r9on2n_QfnWF1-e255V1zgJInJPIFM7itLE91UwYXtUznwJwN-UV3ZlG6dXYznep3L
yjqEPSRDbJ6_-y1yTYBAYPPVkIR0slyM3TPa2h9X18LF5r4vmt4U_N27_GAWNIujflzA

It's important to note that the contents of the userinfo endpoint are publicly available, and should not include any sensitive information without the user's consent.