How to make authenticated calls to mutations and queries?
Hello people,
I am creating a game in next.js and using Convex for it, plust Clerk for website authentication.
My question is, tha do i need to check or make authenticated calls for mutations and queries, when for exmaple I want to send the Chat messages, users will write in the Chat functionality, to Convex database?
Does the
ctx.auth
object have other possibilities other than getUserIdentity? Or maybe I'm viewing it from the wrong angle, about how to use authentication in Convex queries and mutaitons.
If so, is there an exmaple for this, which could help me wrap my head around it?9 Replies
If you set up Clerk correctly
ctx.auth.getUserIdentity()
should be automatically filled out in queries and mutation functions.
https://docs.convex.dev/auth/clerkConvex Clerk | Convex Developer Hub
Clerk is an authentication platform providing login via
In my code i use it like this:
and in your mutation or query you can get the auth from
ctx.auth
or { auth }
The data in getUserIdentity
is already set for you by convex when you pass clerks useAuth hook to the ConvexProviderWithClerk
https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims is the standard they follow for the identity
Final: OpenID Connect Core 1.0 incorporating errata set 1
OpenID Connect Core 1.0 incorporating errata set 1
@Indy @CodingWithJamal Thank you for the examples
no problem
My app keeps meeting the if (!identity) condition and going down the 'No Identity found' path. What steps can I do to troubleshoot?
I will get an error on the front end like:
Unhandled Runtime Error
Error: [CONVEX Q(userSettings:getUserSettingsByTokenIdentifier)] [Request ID: c162d4695c70ec96] Server Error
Uncaught Error: Unauthenticated call to function
at handler (../convex/userSettings.ts:107:4)
Called by client
Does a line like this
const identity = await ctx.auth.getUserIdentity();
only work in Convex mutations and not queries?
Looking through each of the Next.js apps in the Convex templates, I dont see this line:
const identity = await ctx.auth.getUserIdentity();
in any query
So this code in /convex/userSettings.ts will throw that unhandled runtime error:
export const getUserSettingsByTokenIdentifier = query({
handler: async (ctx) => {
// Get the user identity, which includes the tokenIdentifier
const identity = await ctx.auth.getUserIdentity();
// If there's no identity found, invalidate the request (unauthenticated)
if (!identity) {
throw new Error('Unauthenticated call to function');
}
const user = await ctx.db
.query('users')
.withIndex('by_token', (q) =>
q.eq('tokenIdentifier', identity.tokenIdentifier),
)
.unique();
if (!user) {
throw new Error('User not found in users');
}
// Then, query the userSettings table using the obtained user._id
const userSettings = await ctx.db
.query('userSettings')
.filter((q) => q.eq(q.field('userId'), user._id))
.first();
// If no settings are found for the user, throw an error
if (!userSettings) {
throw new Error('Settings not found for this user');
}
return userSettings;
},
});
Source of the error where the query is called:
src/app/(try-convex)/two-part-query-function/page.tsx (29:5) @ api
27 |
28 | const selectUserSettingsData = useQuery(
29 | api.userSettings.getUserSettingsByTokenIdentifier,| ^ 30 | ); 31 | The spirit of what I am trying to do is use one query function, getUserSettingsByTokenIdentifier, to 1) get the tokenIdentifier from Clerk 2) select from the users table 3) select from the userSettings table. The exception is happening because the identity is not found in the query function.
Following https://docs.convex.dev/auth/debug
Seems like I am not getting an Authenticate message at all
is the
useQuery
inside a component that is nested inside a <Authenticated>
component?Ah, no it is not. my app is not using <Authenticated> anywhere. I thought that since my page.tsx is required by Clerk middleware.ts to be authenticated, then <Authenticated> was not necessary
@lee - I think there is some coding issue that VS Code is not warning me about.
If I simplify things and just try to get the userIdentity (and not the user settings) from my Next.js page.tsx:
const authUserIdentity = useQuery(api.userSettings.queryAuthUserIdentity, {});
I am able to successfully see the type: "Authenticate" message in my console log, as well as render the userIdentity on my front end.
Here is the relevant code from my /convex/userSettings.ts:
But when I try to make my page.tsx call my Convex query function, getUserSettingsByTokenIdentifier, that does multiple steps,
1) get the userIdentity
2) select from users
3) select from userSettings
This is when I get in this situation where Chrome is not even showing an Authenticate message in my console log.