wiley
September 2, 2022, 12:46am
1
Based on the example here:
Customize Email Handling
my code looks like this:
function VerifyEmailButton() {
const { user, getAccessTokenSilently } = useAuth0();
const onVerificationEmail = async () => {
var axios = require("axios").default;
const domain = process.env.REACT_APP_AUTH0_DOMAIN;
const clientId = process.env.REACT_APP_AUTH0_CLIENT_ID;
const audience = process.env.REACT_APP_AUTH0_AUDIENCE;
const { email } = user;
const token = await getAccessTokenSilently();
const url = `https://${domain}/api/v2/jobs/verification-email`;
const authorization = `Bearer ${token}`;
//const organization_id = 'blah';
const options = {
method: "POST",
url: url,
headers: {
"content-type": "application/json",
authorization: authorization,
},
data: {
user_id: email,
client_id: clientId,
// audience: audience,
identity: {
user_id: "5457edea1b8f22891a000004",
provider: "google-oauth2",
},
// organization_id: organization_id,
},
};
axios
.request(options)
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.error(error);
});
};
return (
<button className="btn btn-primary btn-lg" onClick={onVerificationEmail}>
Resend Email Verification
</button>
);
}
When it executes, I get 401, complaining about bad audience :
"{"statusCode":401,"error":"Unauthorized","message":"Bad audience: XXXXXX https://YYYYYYY.us.auth0.com/userinfo\“}”
I’m using my audience elsewhere, and it’s working, so I’m pretty confident I have the audience right, even though in the sample program audience isn’t used at all.
I’ve also tried adding ‘audience’ to ‘options | data’ (now commented out) but that didn’t help.
tyf
September 2, 2022, 1:24am
3
Hey @wiley !
wiley:
I’m using my audience elsewhere, and it’s working, so I’m pretty confident I have the audience right, even though in the sample program audience isn’t used at all.
I’ve also tried adding ‘audience’ to ‘options | data’ (now commented out) but that didn’t help.
I’m not entirely sure of your flow here, but you’re going to need to use a Management API Access Token which will have an audience of the identifier of your tenant’s Management API: https://YOUR_DOMAIN.us.auth0.com/api/v2/
in order to successfully hit the /api/v2/jobs/verification-email endpoint.
Hope this helps at least get you started in the right direction
wiley
September 2, 2022, 2:58am
4
Trying to figure out how to do that in a SPA. The main article on that (Get Management API Access Tokens for Single-Page Applications ) skips that detail (no explanation or links).
tyf
September 2, 2022, 7:22pm
6
Hey @wiley you’ll basically need to use some sort of a proxy to make calls to the management API on behalf of your SPA app. If using the front end directly, there are strict limitations as outlined in the article you posted. This is a security precaution given the fact that it’s in the context of a public application - The following resources should help:
Last Updated: Aug 8, 2024
Overview
This article provides details on how to enable users to change their email address from a SPA or native app.
Applies To
SPA
Native App
Email address
Solution
Public clients (like SPAs and native applications) are restricted from requesting tokens for the management API with the proper scopes for updating a user’s email. These types of applications are limited to a few specific scopes . Because of these limitations, email change requests from public clients m…
I am trying to get user metadata for a logged in user. Given that the login gives me an access token and not an id token. So I can’t add the user metadata that way and there does not seem to be a way to extend the information that is returned on the /userinfo API. I figure the only way to get the user metadata would be for the user to be able to user the Management API. So I attempted to user the access token to access the Management API and that is a no go. I am using the Auth0Client to do the …
No worries! Good to know that was helpful
You will need both - The SPA app configured in Auth0 will be specific to your React App/client side. On the other hand, you will have a M2M app configured in Auth0 specific to your own API/backend. The flow would look like this:
User logs in to your React/SPA app.
User goes to perform something (get all users for instance) that requires Management API use.
This is really where the magic happens - Instead of your React app communicating direct…
1 Like
wiley
September 2, 2022, 7:56pm
7
I get that SPA’s have unique security concerns. But in the list of available scopes to SPA’s, ‘resend email verification’ is not listed, and I don’t get the security risk.
1 Like
tyf
September 2, 2022, 9:36pm
8
That’s correct - The scope required is update:users
which is not one of the scopes available to a SPA app requesting a Management API Token. This is where the proxy approach comes into play allowing that service to communicate with the Management API on behalf of your SPA app with a fully scoped access token.
1 Like
wiley
September 6, 2022, 12:57am
9
OK, limited privileges in SPAs makes sense. So I’ve moved it to my backend. Here’s my code:
const myDomain = "https://MY_DOMAIN.us.auth0.com";
const myClientId = "MANAGEMENT_API_CLIENT_ID";
const myClientSecret = 'MANAGEMENT_API_CLIENT_SECRET';
const myUserId = "auth0|A_USER_WITH_UNVERIFIED_EMAIL";
// GET A TOKEN
const url1 = `${myDomain}/oauth/token`;
const headers1 = { "content-type": "application/json" };
const body1 = {
client_id: myClientId,
client_secret: myClientSecret,
audience: `${myDomain}/api/v2/`,
grant_type: "client_credentials",
//scope: 'update:users' // I thought I needed this, but it generates an error (?)
};
let access_token;
const res1 = await axios
.post(url1, body1, headers1)
.then((res) => {
console.log(`Status1: ${res.status}`);
console.log(`Body1: ${res.data}`);
access_token = res.data.access_token;
})
.catch((err) => {
console.error(err);
return;
});
// REQUEST RESEND VERIFICATION EMAIL
const url2 = `${myDomain}/api/v2/jobs/verification-email`;
const headers2 = {
"Content-Type": "application/json",
Authorization: `Bearer ${access_token}`,
};
const body2 = {
user_id: myUserId,
};
const res2 = await axios
.post(url2, body2, headers2)
.then((res) => {
console.log(`Status1: ${res.status}`);
console.log(`Body1: ${res.data}`);
})
.catch((err) => {
console.error(err);
return;
});
In the Management API, I have enabled my backend to access the Management API.
When I execute my code, I do get a token, but when I do the ‘resend email verification’ call I get:
statusCode: 401,
error: ‘Unauthorized’,
message: ‘Missing authentication’
What am I missing?
wiley
September 7, 2022, 11:20pm
10
HERE’S THE SOLUTION: See this working example:
tyf
September 8, 2022, 12:33am
11
Good idea! I apologize for the delayed response here, but thanks for sharing the blog post and confirming your findings with the community
tyf
Closed
September 23, 2022, 12:34am
12
This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.