oscklm
oscklm6mo ago

[ConvexAuth] getting jwtToken to pass to auth headers in fetch on client

Is there a way to get the jwtToken client side when authenticated, when using convex auth? i'd like to pass it in the auth headers of a fetch request from my client
fetch("https://<deployment name>.convex.site/uploadImage", {
headers: {
Authorization: `Bearer ${jwtToken}`,
},
});
fetch("https://<deployment name>.convex.site/uploadImage", {
headers: {
Authorization: `Bearer ${jwtToken}`,
},
});
Like for example with clerk you could do something like:
auth().getToken({ template: "convex" })
auth().getToken({ template: "convex" })
16 Replies
oscklm
oscklmOP6mo ago
I'm trying to secure this http action:
export const uploadImage = httpAction(async (ctx, request) => {
// Confirm authentication
const identity = await ctx.auth.getUserIdentity();

if (!identity) {
return new Response('Authentication required', {
status: 401,
headers: {
'Access-Control-Allow-Origin': process.env.SITE_URL,
Vary: 'Origin',
},
});
}

// Step 1: Store the file
const blob = await request.blob();
const storageId = await ctx.storage.store(blob);

// Step 2: Create the image document
const imageId = await ctx.runMutation(api.image.mutations.insertOne, {
kind: 'videoThumbnail',
originalId: storageId,
thumbnailIds: null,
});

// Step 3: Return the imageId in the response with CORS headers
const responseBody = {
message: 'Image uploaded successfully',
storageId: storageId.toString(),
imageId: imageId.toString(),
};

return new Response(JSON.stringify(responseBody), {
status: 200,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': process.env.SITE_URL,
Vary: 'Origin',
},
});
});
export const uploadImage = httpAction(async (ctx, request) => {
// Confirm authentication
const identity = await ctx.auth.getUserIdentity();

if (!identity) {
return new Response('Authentication required', {
status: 401,
headers: {
'Access-Control-Allow-Origin': process.env.SITE_URL,
Vary: 'Origin',
},
});
}

// Step 1: Store the file
const blob = await request.blob();
const storageId = await ctx.storage.store(blob);

// Step 2: Create the image document
const imageId = await ctx.runMutation(api.image.mutations.insertOne, {
kind: 'videoThumbnail',
originalId: storageId,
thumbnailIds: null,
});

// Step 3: Return the imageId in the response with CORS headers
const responseBody = {
message: 'Image uploaded successfully',
storageId: storageId.toString(),
imageId: imageId.toString(),
};

return new Response(JSON.stringify(responseBody), {
status: 200,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': process.env.SITE_URL,
Vary: 'Origin',
},
});
});
erquhart
erquhart6mo ago
Why not use an action instead of an http route?
sshader
sshader6mo ago
Yeah not currently exposed (we made https://github.com/get-convex/convex-auth/issues/38 to track). In terms of workarounds for now, you could go for this path using storage.generateUploadUrl (https://docs.convex.dev/file-storage/upload-files#uploading-files-via-upload-urls), and check auth in the mutation that produces the upload URL, or potentially switch to a normal action (and be okay with only being able to upload files up to 8MB with no streaming to fall under the function argument size limits)
oscklm
oscklmOP6mo ago
They are not intended to be called client side, as far as i understand? Went ahead and read the docs on the subject again. Def had it twisted the way i set it up. Now it works just how i want it.
Michal Srb
Michal Srb5mo ago
@oscklm you can now authenticate HTTP actions with the useAuthToken hook. https://labs.convex.dev/auth/authz#authenticate-http-actions
Authorization - Convex Auth
Authentication library for your Convex backend
oscklm
oscklmOP5mo ago
Awesome stuff Michael! Thanks for the heads up
samtalksAI
samtalksAI5mo ago
@Michal Srb so does this mean Next JS server components, including middleware.ts is now supported in Convex Auth?
Michal Srb
Michal Srb5mo ago
@samtalksAI there’s an alpha release, check it out and share any feedback: Try out the Next.js alpha: npm i @convex-dev/auth@0.0.48-alpha.0
samtalksAI
samtalksAI5mo ago
@Michal Srb sure thing! Doc still the same right? https://labs.convex.dev/auth/setup Any articles on stack to go over this in more clarity or was the auth example repo updated to show the server side stuff?
Set Up Convex Auth - Convex Auth
Authentication library for your Convex backend
Michal Srb
Michal Srb5mo ago
The docs have the instructions, starting from Setup. And there's a test-nextjs demo in the convex-auth repo.
jCtapuk
jCtapuk5mo ago
https://docs.convex.dev/api/classes/browser.ConvexHttpClient After authorization, where can I get a token so that I can transfer it to my backend, where it will process the request?@Michal Srb
Michal Srb
Michal Srb5mo ago
Authorization - Convex Auth
Authentication library for your Convex backend
jCtapuk
jCtapuk5mo ago
That's not it. I'm using
const { tokens } = fetch(`${process.env.SITE_URL}/api/action', {path: "auth:signIn", format: "json", args: {provider: "anonymous"} })
const { tokens } = fetch(`${process.env.SITE_URL}/api/action', {path: "auth:signIn", format: "json", args: {provider: "anonymous"} })
I had to look for these functions under the hood, there is no such information in the documentation or I missed it... I need to access your backend through the backend of my server. And get a token and not a frontend one
Michal Srb
Michal Srb5mo ago
There's an alpha out for Next.js. Can you open a new thread and describe all the relevant details? (What's your fronted, what's your additional server)
jCtapuk
jCtapuk5mo ago
@Michal Srb only astro ssr + integrated vue so I do something like
export function useConvexClient() {
let client
if (import.meta.server) {
// Save client http no reactive
} else {
// Save client reactive
}
return client
}
export function useConvexClient() {
let client
if (import.meta.server) {
// Save client http no reactive
} else {
// Save client reactive
}
return client
}
Michal Srb
Michal Srb5mo ago
We don't have SSR support for this in Astro. You can look at how the Next.js integration works and try to replicate it for Astro (1. proxy auth actions through the astro server, 2. store tokens in cookies).

Did you find this page helpful?