Skip to content

Auth integration

Everything happens in your launch handler. It receives a verified LaunchResult; you:

  1. normalize claims with ltiIdentity(),
  2. find-or-create your user (your DB) — keyed on sub, not email,
  3. start a session with your auth library,
  4. set the session cookie iframe-safe and redirect.
import { launch, sessionRedirect } from '@ltikit/next'
import { ltiIdentity } from '@ltikit/core'
export const POST = launch(lti, async (result) => {
const id = ltiIdentity(result.claims)
const user = await upsertUserByLtiSub(id) // your DB (Prisma/Drizzle/Supabase)
const sessionValue = await createSession(user) // your auth lib's server API
return sessionRedirect({
to: `${process.env.APP_URL}/home`,
cookies: [{ name: 'session', value: sessionValue, maxAgeSec: 60 * 60 * 8 }],
})
})

Three constraints (LTI-iframe realities, not per-library):

  • SameSite=None; Secure — cross-site LMS iframe; add Partitioned (CHIPS). sessionRedirect handles it.
  • Set it in the launch response — the first request is a cross-site POST.
  • Identify by sub (+ issuer)email may be absent (Canvas Test Student).

ltiIdentity(claims){ sub, issuer, email?, name?, givenName?, familyName?, roles, isInstructor, isLearner, contextId?, contextTitle?, resourceLinkId? }.

Either sign in via a Credentials provider with the verified sub (trusted — LTIkit already verified it), or mint the Auth.js session JWT directly. Configure the session cookie for the iframe:

// auth config
cookies: {
sessionToken: {
name: 'next-auth.session-token',
options: { httpOnly: true, sameSite: 'none', secure: true, path: '/' },
},
}

A full working example (Next.js + Prisma + NextAuth) lives in examples/next-prisma-demo.

  • Cookie without SameSite=None; Secure → silently dropped in the iframe → user looks logged out.
  • Relying on email → breaks for no-email users. Key on sub.
  • Setting the session on a later page instead of the launch response → the cross-site POST has no session yet.
  • Third-party cookie deprecation → add Partitioned (CHIPS); the long-term fix is LTI Platform Storage (cookieless), on the roadmap.