nikhildhoka
nikhildhoka4w ago

/authenticate route to get the Bearer Token of the user given their username and pass using Clerk

How can I fix this httpAction to use Clerk to get the Bearer token of the user based on the username and password that the user will provide in the request body of the api call to convex:
import { httpAction } from "../_generated/server";
import { Clerk } from "@clerk/clerk-js";

export const authenticateHandler = httpAction(async (ctx, request) => {
try {
// Parse the request body
const { User, Secret } = await request.json();

// Authenticate the user using Clerk's users API
const user = await clerk.users.verifyPassword({ identifier: User, password: Secret });

if (user) {
// Create a session for the authenticated user
const session = await clerk.sessions.createSession({ userId: user.id });

// Retrieve the session token
const token = session.token;

// If authentication is successful, return the token
return new Response(JSON.stringify({
token: token,
}), { status: 200 });
}
} catch (error: any) {
if (error.message.includes("invalid credentials")) {
// Return 401 if the user or password is invalid
return new Response("The user or password is invalid.", { status: 401 });
}

// If any required fields are missing, return 400
if (error.message.includes("missing fields")) {
return new Response("There is missing field(s) in the AuthenticationRequest or it is formed improperly.", { status: 400 });
}

// Return 501 if the system does not support authentication
return new Response("This system does not support authentication.", { status: 501 });
}

// Ensure a Response is returned if no other conditions are met
return new Response("An unexpected error occurred.", { status: 500 });
// return new Response(JSON.stringify({messsage: "Hello world!"}), {
// status: 200,
// });
});
import { httpAction } from "../_generated/server";
import { Clerk } from "@clerk/clerk-js";

export const authenticateHandler = httpAction(async (ctx, request) => {
try {
// Parse the request body
const { User, Secret } = await request.json();

// Authenticate the user using Clerk's users API
const user = await clerk.users.verifyPassword({ identifier: User, password: Secret });

if (user) {
// Create a session for the authenticated user
const session = await clerk.sessions.createSession({ userId: user.id });

// Retrieve the session token
const token = session.token;

// If authentication is successful, return the token
return new Response(JSON.stringify({
token: token,
}), { status: 200 });
}
} catch (error: any) {
if (error.message.includes("invalid credentials")) {
// Return 401 if the user or password is invalid
return new Response("The user or password is invalid.", { status: 401 });
}

// If any required fields are missing, return 400
if (error.message.includes("missing fields")) {
return new Response("There is missing field(s) in the AuthenticationRequest or it is formed improperly.", { status: 400 });
}

// Return 501 if the system does not support authentication
return new Response("This system does not support authentication.", { status: 501 });
}

// Ensure a Response is returned if no other conditions are met
return new Response("An unexpected error occurred.", { status: 500 });
// return new Response(JSON.stringify({messsage: "Hello world!"}), {
// status: 200,
// });
});
3 Replies
Convex Bot
Convex Bot4w ago
Thanks for posting in <#1088161997662724167>. Reminder: If you have a Convex Pro account, use the Convex Dashboard to file support tickets. - Provide context: What are you trying to achieve, what is the end-user interaction, what are you seeing? (full error message, command output, etc.) - Use search.convex.dev to search Docs, Stack, and Discord all at once. - Additionally, you can post your questions in the Convex Community's <#1228095053885476985> channel to receive a response from AI. - Avoid tagging staff unless specifically instructed. Thank you!
ballingt
ballingt4w ago
Is that something that Clerk supports? You want to do this the same way you would in another HTTP server. I looks like you have some code, where is this from? Is this not working? What error do you see?
nikhildhoka
nikhildhokaOP3w ago
nvm I was able to figure it out using a combination of their backend sdk and their api
try {
// Parse the request body
const { User, Secret } = await request.json();
const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY, publishableKey: process.env.VITE_CLERK_PUBLISHABLE_KEY });
const users = await clerkClient.users.getUserList({query: User["name"]});

try {
// Parse the request body
const { User, Secret } = await request.json();
const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY, publishableKey: process.env.VITE_CLERK_PUBLISHABLE_KEY });
const users = await clerkClient.users.getUserList({query: User["name"]});

const userId = users["data"][0]["id"];
const passwordVerification = await clerkClient.users.verifyPassword({userId, password: Secret["password"]});
console.log(passwordVerification);
if (!passwordVerification["verified"]) {
throw new Error("invalid credentials");
}
//create a new session and then create a new jwt token for the session
const response = await fetch('https://api.clerk.com/v1/sessions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.CLERK_SECRET_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ user_id: userId }),
});

const session = await response.json();
const sessionId = session["id"];
// call the https://api.clerk.com/v1/sessions/{session_id}/tokens/convex endpoint to create a new token
const tokenResponse = await fetch(`https://api.clerk.com/v1/sessions/${sessionId}/tokens/convex`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.CLERK_SECRET_KEY}`,
'Content-Type': 'application/json',
},
});
const tokenJSON = await tokenResponse.json();
const token = tokenJSON["jwt"];
return new Response(JSON.stringify("Bearer "+ token), { status: 200 });

const userId = users["data"][0]["id"];
const passwordVerification = await clerkClient.users.verifyPassword({userId, password: Secret["password"]});
console.log(passwordVerification);
if (!passwordVerification["verified"]) {
throw new Error("invalid credentials");
}
//create a new session and then create a new jwt token for the session
const response = await fetch('https://api.clerk.com/v1/sessions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.CLERK_SECRET_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ user_id: userId }),
});

const session = await response.json();
const sessionId = session["id"];
// call the https://api.clerk.com/v1/sessions/{session_id}/tokens/convex endpoint to create a new token
const tokenResponse = await fetch(`https://api.clerk.com/v1/sessions/${sessionId}/tokens/convex`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.CLERK_SECRET_KEY}`,
'Content-Type': 'application/json',
},
});
const tokenJSON = await tokenResponse.json();
const token = tokenJSON["jwt"];
return new Response(JSON.stringify("Bearer "+ token), { status: 200 });

Did you find this page helpful?