#authorize inside http actions
1 messages · Page 1 of 1 (latest)
Hi @minor rapids. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
To have ctx.auth.getUserIdentity() return a UserIdentity in an HTTP action, you must send a valid JWT in the Authorization header of the HTTP request.
Request requirement
GET <https://<deployment-name>.convex.site/myAction>
Authorization: Bearer <your-jwt-token>
On the server, your HTTP action can then do:
import { httpRouter } from "convex/server";
import { httpAction } from "./_generated/server";
const http = httpRouter();
http.route({
path: "/myAction",
method: "GET",
handler: httpAction(async (ctx, request) => {
const identity = await ctx.auth.getUserIdentity();
// identity is null if the token is missing/invalid
// otherwise it's a UserIdentity
// ...
return new Response("ok");
}),
});
export default http;
This pattern—sending Authorization: Bearer <JWT>—is what Convex expects for authenticating HTTP actions so that ctx.auth.getUserIdentity() can resolve to the current user. [Auth in functions; HTTP actions auth]
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@minor rapids Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@past sluice how do i access the jwt token on the frontend?
Let me check the knowledge base for you again. One moment! :books:
To access the JWT token on the frontend, use the Convex Auth React hook useAuthToken and then pass it in the Authorization header when calling your HTTP action.
Example:
import { useAuthToken } from "@convex-dev/auth/react";
function SomeComponent() {
const token = useAuthToken();
const onClick = async () => {
const res = await fetch(`${process.env.VITE_CONVEX_SITE_URL!}/someEndpoint`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
// ...
};
// ...
}
useAuthToken() returns string | null with the JWT Convex uses for ctx.auth.getUserIdentity() in HTTP actions. [useAuthToken hook; Auth HTTP actions]
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@minor rapids Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@past sluice i get an cors error
Let me check the knowledge base for you again. One moment! :books:
You’re on the right track; when calling Convex HTTP actions from the browser with a custom fetch (e.g. to send the JWT), you must add CORS handling on the Convex side. The CORS error is almost certainly because the HTTP action isn’t returning the right CORS headers and/or isn’t handling the preflight OPTIONS request.
Here are two ways to fix it.
1. Minimal manual CORS setup
In convex/http.ts, add CORS headers to your endpoint and handle OPTIONS for preflight:
import { httpRouter } from "convex/server";
import { httpAction } from "./_generated/server";
const http = httpRouter();
http.route({
path: "/someEndpoint",
method: "POST",
handler: httpAction(async (ctx, request) => {
// ... your logic (can use ctx.auth.getUserIdentity()) ...
return new Response("ok", {
status: 200,
headers: new Headers({
// e.g. <https://your-frontend.com,> or from env
"Access-Control-Allow-Origin": process.env.CLIENT_ORIGIN!,
Vary: "origin",
}),
});
}),
});
// Pre-flight for /someEndpoint
http.route({
path: "/someEndpoint",
method: "OPTIONS",
handler: httpAction(async (_, request) => {
const headers = request.headers;
if (
headers.get("Origin") !== null &&
headers.get("Access-Control-Request-Method") !== null &&
headers.get("Access-Control-Request-Headers") !== null
) {
return new Response(null, {
headers: new Headers({
"Access-Control-Allow-Origin": process.env.CLIENT_ORIGIN!,
"Access-Control-Allow-Methods": "POST",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
"Access-Control-Max-Age": "86400",
}),
});
} else {
return new Response();
}
}),
});
export default http;
This is the same pattern Convex uses for file upload HTTP actions and general CORS examples. [HTTP CORS example; Upload HTTP action]
2. Use the corsRouter helper (simpler)
If you’re okay adding convex-helpers, you can let it generate the CORS + OPTIONS handling for you:
import { httpRouter } from "convex/server";
import { corsRouter } from "convex-helpers/server/cors";
import { httpAction } from "./_generated/server";
const http = httpRouter();
const cors = corsRouter(http, {
allowedOrigins: ["<https://your-frontend.com"],> // or "*"
allowedHeaders: ["Content-Type", "Authorization"],
});
// Your endpoint with CORS support
cors.route({
path: "/someEndpoint",
method: "POST",
handler: httpAction(async (ctx, request) => {
// ... your logic ...
return new Response("ok");
}),
});
export default http;
corsRouter automatically creates the matching OPTIONS route and headers. [CORS helper; Discord CORS helper usage]
Quick checklist
- Use
.convex.siteURL in yourfetch, not.convex.cloud. [HTTP debugging] - Ensure your HTTP action:
- Returns
Access-Control-Allow-Origin(and other needed headers) on the actual response. - Has an
OPTIONShandler (manually or viacorsRouter) for preflight.
- Returns
- In the browser devtools Network tab, confirm:
- An
OPTIONSrequest succeeds (200/204) with CORS headers. - The subsequent
POST/GETalso hasAccess-Control-Allow-Origin.
- An