imightbejesus
imightbejesus5mo ago

await ctx.auth.getUserIdentity() returns null in http action

I have a react app and using Auth0.
<React.StrictMode>
<Auth0Provider
domain={auth0_domain || ""}
clientId={auth0_clientId || ""}
authorizationParams={{
redirect_uri: window.location.origin,
}}
useRefreshTokens={true}
cacheLocation="localstorage"
>
<ConvexProviderWithAuth0 client={convex}>
<App/>
</ConvexProviderWithAuth0>
</Auth0Provider>
</React.StrictMode>
<React.StrictMode>
<Auth0Provider
domain={auth0_domain || ""}
clientId={auth0_clientId || ""}
authorizationParams={{
redirect_uri: window.location.origin,
}}
useRefreshTokens={true}
cacheLocation="localstorage"
>
<ConvexProviderWithAuth0 client={convex}>
<App/>
</ConvexProviderWithAuth0>
</Auth0Provider>
</React.StrictMode>
I am able to authenticate the user and get access token from Auth0, however when I pass this token to Authorization header of a request to http action, in my http action - await ctx.auth.getUserIdentity() returns null.
const { getAccessTokenSilently } = useAuth0();
let token: string;
getAccessTokenSilently().then(t => token = t);
const { getAccessTokenSilently } = useAuth0();
let token: string;
getAccessTokenSilently().then(t => token = t);
await fetch(`${convexSiteUrl}/chat`, {
method: "POST",
body: JSON.stringify(requestBody),
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`,
},
});
await fetch(`${convexSiteUrl}/chat`, {
method: "POST",
body: JSON.stringify(requestBody),
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`,
},
});
What am I missing here? Thanks in advance.
22 Replies
imightbejesus
imightbejesusOP5mo ago
Confirming that access token is indeed passed to the action endpoint.
Jacob Kim
Jacob Kim5mo ago
https://discord.com/channels/1019350475847499849/1270746067582980129 same issue reported here. this happened to me about a day ago.
imightbejesus
imightbejesusOP5mo ago
@Jacob Kim I appreciate you referencing the thread, however I don't think I am experiencing the same issue. I don't use convex auth or nextjs. This is just a react app with Auth0. I've upgraded to convex@1.14.0 and that made no difference. As stated above - I see the token in the headers of my request to the post http endpoint of convex, however await ctx.auth.getUserIdentity() still returns null. Still looking for advice here.
erquhart
erquhart5mo ago
'twas the weekend, Monday catch up is coming Not sure who best to cc here, maybe @Michal Srb
imightbejesus
imightbejesusOP5mo ago
My guess is that I need to specify audience in authorizationParams when initializing Auth0Provider. Should it be
process.env.REACT_APP_CONVEX_URL?.replace(
/\.cloud$/,
".site"
)
process.env.REACT_APP_CONVEX_URL?.replace(
/\.cloud$/,
".site"
)
? Do I also need to register convex API using the same url on Auth0 side of things?
Michal Srb
Michal Srb5mo ago
@imightbejesus try
const response = await getAccessTokenSilently({
detailedResponse: true,
cacheMode: "off",
});
const response = await getAccessTokenSilently({
detailedResponse: true,
cacheMode: "off",
});
especially the first flag might be improtant to get the token in the right format. Consult https://docs.convex.dev/auth/debug to compare the JWT used by the React client with the one you're getting, my guess is without the flag they are different.
Debugging Authentication | Convex Developer Hub
You have followed one of our authentication guides but something is not working.
imightbejesus
imightbejesusOP5mo ago
@Michal Srb that made no difference. Access token is not being validated correctly by the convex. await ctx.auth.getUserIdentity() returns null. If I send id_token - it works. But the whole point is that I should be sending access token. Which needs to be verified by the backend.
ballingt
ballingt5mo ago
What's your motivation for using the access token instead of the id token? This is currently set up to return the verified information from the identity token (ie getUserIdentity()) I may be confused here, I need to read up on Convex Auth
imightbejesus
imightbejesusOP5mo ago
Auth0 - Blog
ID Token and Access Token: What Is the Difference?
Learn what ID and access tokens are and how to correctly use them in the OpenID Connect and OAuth context.
imightbejesus
imightbejesusOP5mo ago
To be clear, I don't care about getting user identity in an http action, I just need a way to verify that whoever hits the exposed endpoint is authorized to do so. @ballingt I find the terminology you used a bit confusing. If by Convex Auth you mean - exactly Convex Auth - then this is likely not directly related to my issue, as I do not use Convex Auth. But if you mean auth in Convex in general and specifically via Auth0 - then yes, that is related to my question.
ballingt
ballingt5mo ago
Ah great, then I'm familiar with this. Convex just uses Identity tokens. There's no built-in support for auth tokens, you'll need to verify them yourself for whatever kind of authorization system you're building. The auth.getUserIdentity() function returns the claims from an identity token.
imightbejesus
imightbejesusOP5mo ago
This seems wrong. It sounds like your docs encourage to put id token into Authorization header (even though this is not stated explicitly, based on this thread - that's what I understand). (https://docs.convex.dev/auth/functions-auth#http-actions) While Authorization token should contain an access token. Now if I needed to use auth.getUserIdentity() in my http action, I won't be able to do so if I am passing correct token to the Authorization header.
Auth in Functions | Convex Developer Hub
_If you're using Convex Auth, see the
Michal Srb
Michal Srb5mo ago
Think of it this way: The access token is for third-party services that you don't necessarily trust. The Convex backend is part of your server architecture. Giving it the ID token from Auth0 is OK. I agree that this is confusing and doesn't seem right from Auth0 docs.
imightbejesus
imightbejesusOP5mo ago
Access token is for third party services that I don't trust, agree. However I need to call these third party services from convex http action. So I need to pass an access token in Authorization header of the request to my convex http action, in order to be able to use it with whatever is going on inside of the http action.
Michal Srb
Michal Srb5mo ago
Ah, in that case you want to pass the access token through the body of the request. The bearer <token> header is for making ctx.auth.getUserIdentity() working (which seemed to be what you originally wanted).
await fetch(`${convexSiteUrl}/chat`, {
method: "POST",
body: JSON.stringify({
accessToken,
}),
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${idToken}`,
},
});
await fetch(`${convexSiteUrl}/chat`, {
method: "POST",
body: JSON.stringify({
accessToken,
}),
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${idToken}`,
},
});
imightbejesus
imightbejesusOP5mo ago
I will need to get back to you with some concrete arguments against this, but from the gut feeling - passing an access token as a part of a body seems like a hack, a wrong one. Also what about GET requests? Where should I put access token in those?
Web Dev Cody
Web Dev Cody5mo ago
I'm logged in this prints null
ballingt
ballingt5mo ago
@Web Dev Cody could you open a new thread? This one isn't about Convex Auth. (because this confused me before) You can add these as a different header. For Convex HTTP endpoints if there is an Authorization header it's assumed to be the identity token so that auth.getUserIdentity() works.
Michal Srb
Michal Srb5mo ago
@imightbejesus actually a better solution for you might be to fetch the acess token from Auth0 from the Convex server. Then you only pass the ID token to the Convex server, and use the Auth0 server-side API to fetch an access token to use with external services.
imightbejesus
imightbejesusOP5mo ago
Okay. Perhaps the Convex docs need to be updated with which token to pass in Authorization header.
Web Dev Cody
Web Dev Cody5mo ago
opps yes sorry
Michal Srb
Michal Srb5mo ago
@imightbejesus good feedback, thanks!

Did you find this page helpful?