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.