How to generate JWT for server-side requests (Twilio webhooks) in BetterAuth v1.3?

Hi all, I'm using BetterAuth with a Next.js app and I'm handling incoming Twilio SMS webhooks to interact with users based on their phone number. Previously, I used: import { getJwtToken } from "better-auth/plugins/jwt/sign"; to create a JWT manually so I could simulate a user session when Twilio hits my webhook. But after upgrading to BetterAuth v1.3, this import no longer works. Here’s what I’m doing: I match the incoming From number to a user in my DB (users have a unique phone number). I validate their role and phone verification. Then, I was creating a session and generating a JWT token to pass to an internal LLM agent via a RuntimeContext. Now I’m not sure what the best way is to generate that JWT in v1.3. What’s the recommended approach to simulate or generate a JWT for a known user (e.g., via their userId) for trusted backend requests like Twilio webhooks? Appreciate any guidance!
8 Replies
LightTab2
LightTab22mo ago
https://github.com/better-auth/better-auth/pull/2755 I am afraid this moved things around and hid the getJwtToken method
GitHub
fix(oidc): use JWT plugin if enabled to sign keys by NefixEstrada ...
With this PR, if the JWT plugin is enabled, the OIDC plugin will use it to issue valid JWT tokens, following the published JWKS keys as the metadata endpoint suggests it should.
Ping
Ping2mo ago
I'll open a PR to bring it back.
Ping
Ping2mo ago
GitHub
fix(JWT): Re-export the getJwtToken function by ping-maxwell · Pul...
In a previous RP, we removed the export for that function which caused an unintentional breaking change. This will fix it. Summary by cubic Re-exported the getJwtToken function from the JWT plugi...
DrMandelbrot
DrMandelbrotOP2mo ago
Thanks! What I finally did, is this: const ctx = await auth.$context; // --- Create session for JWT --- const mockContext = { headers: new Headers({ "user-agent": "Twilio-Server", }), context: ctx, }; const session = await ctx.internalAdapter.createSession( user.id, mockContext as any, false, { source: "twilio", phoneNumber: fromE164, } ); console.log("🔑 User session:", session); console.log("🔑 Session JWT:", session.token); const jwtResponse = await auth.api.getToken({ headers: { authorization: Bearer ${session.token}, }, }); const jwtToken = jwtResponse.token; I am not sure if this is the right way to do it, as the documentation is not clear. I used github copilot on the repo to discover this method.
LightTab2
LightTab22mo ago
This spams your database with fake sessions
DrMandelbrot
DrMandelbrotOP2mo ago
oh thanks for your input! What would be the best way to do this?
LightTab2
LightTab22mo ago
For now you can revoke this session instantly after creating it
await context.internalAdapter.deleteSession({
token: "session-token"
})
await context.internalAdapter.deleteSession({
token: "session-token"
})
But it's not your fault things got messy, we gotta wait for the fix
DrMandelbrot
DrMandelbrotOP2mo ago
thank you!

Did you find this page helpful?