Hi,
I am new to Auth0. Please be gentle
I use React and I am trying to get an API response with the role assigned to that specific user via the Users > Roles on the dashboard.
If I call the hook ‘useAuth0().user’, I am getting only some basic info about the user.
Up to now, the only way for me to see the roles in the response by calling useAuth0().user, it’s by adding the metadata manually from the Users > Details > app_metadata and user_metadata dashboard and create a Rule.
I can’t manually add a metadata to each user. I should be able to see the Roles for that user without having to do the manual work.
Here my code:
const { user, getAccessTokenSilently } = useAuth0();
const [userMetadata, setUserMetadata] = React.useState(null);
React.useEffect(() => {
const getUserMetadata = async () => {
const domain = "dev-abcd.eu.auth0.com";
try {
const accessToken = await getAccessTokenSilently({
audience: `https://${domain}/api/v2/`,
scope: "read:current_user",
});
const userDetailsByIdUrl = `https://${domain}/api/v2/users/${user.sub}/roles`;
const metadataResponse = await axios.get(userDetailsByIdUrl, {
headers: {
Authorization: `Bearer ${accessToken}`,
}
});
console.log('metadataResponse ==> ', metadataResponse)
const { user_metadata } = await metadataResponse.json();
setUserMetadata(user_metadata);
} catch (e) {
console.log(e.message);
}
};
getUserMetadata();
}, [getAccessTokenSilently, user.sub]);
My console log returns the following:
{roles: Array(1)}
roles: ["admin"]
but this is happening ONLY because I manually set those values in the Users > Details > app_metadata and user_metadata, as explained above. If I remove them, I get an empty Object.
I found an article which explained the possiblity of using the user’s role api. I ended up following the Auth0 documentation: Auth0 Management API v2
Now my code has changed as follow:
const userDetailsByIdUrl = `https://${domain}/api/v2/users/${user.sub}`;
const metadataResponse = await axios.get(userDetailsByIdUrl, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
param: {
scope: "read:users read:roles read:role_members"
}
});
console.log(metadataResponse)
and the response is:
data:
app_metadata:
roles: Array(1)
created_at: "2020-12-28T13:41:35.097Z"
email: "matt@example.com"
email_verified: true
identities: [{…}]
last_ip: "2001:8a0:648a:ef00:5d88:f610:5753:f992"
last_login: "2021-02-19T15:02:17.318Z"
name: "matt"
nickname: "matt"
picture: "https://s.gravatar.com/avatar/a097a0847c295822c6e5407ed3257149?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fma.png"
updated_at: "2021-02-19T18:26:51.634Z"
user_id: "auth0|abcd1234"
user_metadata:
roles: Array(1)
Even if the response is much better, it’s still not correct.
First, I haven’t used the /roles api, which means I am getting only the data for the specific user ID.
Still, the metadata are those hardcoded in the dashboard.
If I change the API url and add /roles, i get an error: Request failed with status code 403
It means : Insufficient scope; expected all of: read:users, read:roles.
I don’t know what to do anymore. Any help is much appreciated.
Matt
By the way, I forgot to mention. This is the script I’ve added to Rules:
function (user, context, callback) {
// This namespace can be whatever you want - it will be the 'key' that holds
// an array of roles on the users token
const namespace = 'userRole';
const assignedRoles = (context.authorization || {}).roles;
console.log(context);
console.log(context.authorization);
console.log(assignedRoles);
let idTokenClaims = context.idToken || {};
let accessTokenClaims = context.accessToken || {};
idTokenClaims[`${namespace}/roles`] = assignedRoles;
accessTokenClaims[`${namespace}/roles`] = assignedRoles;
context.idToken = idTokenClaims;
context.accessToken = accessTokenClaims;
callback(null, user, context);
}