User accounts & auth

env.AUTH is a complete authentication system for your app's own end-users — email + password, sessions, email verification, password reset, and email-based two-factor. It manages its own tables and session cookie; you call methods and return the responses it hands back.

Sign up & sign in

signUp and signIn return a result object. On success it includes a response — a Response with the session cookie already set. Return it (or copy its Set-Cookie) so the browser is signed in:

// api/login.js
export default {
  async fetch(request, env, ctx) {
    const { email, password } = await request.json();
    const r = await env.AUTH.signIn({ email, password });

    if (!r.ok) return Response.json({ error: r.error }, { status: 401 });

    if (r.requires2fa) {
      // a code was emailed; collect it, then call verifyTwoFactorOtp
      await env.AUTH.sendTwoFactorOtp({ otpToken: r.otpToken });
      return Response.json({ requires2fa: true, otpToken: r.otpToken });
    }

    return r.response; // session cookie set
  },
};

signUp({ email, password, name? }) works the same way and returns { ok, user, response }.

Reading the current user

On any request, read who's signed in. getUser returns the user or null; requireUser throws a 401 response if there's no session:

const user = await env.AUTH.getUser(request);
// => { id, email, name, emailVerified, twoFactorEnabled, createdAt } | null

Scope your data queries to user.id.

Two-factor (email OTP)

When a user has 2FA enabled, signIn returns requires2fa: true and an otpToken instead of a session. Email the code, then verify it to complete sign-in:

  • sendTwoFactorOtp({ otpToken }) — email the code.
  • verifyTwoFactorOtp({ otpToken, code }) — returns { ok, user, response }; return the response to set the session.
  • enableTwoFactor(request) / disableTwoFactor(request, { password }).

Other methods

  • signOut(request) → a Response that clears the session cookie.
  • updateUser(request, { name }) — update profile fields.
  • changePassword(request, { current, new }) — revokes other sessions on success.
  • sendVerificationEmail(request) · verifyEmail(token).
  • requestPasswordReset(email) (always returns { ok: true } to avoid account enumeration) · resetPassword({ token, newPassword }).

Sessions & storage

Sessions use an HttpOnly; Secure; SameSite=Lax cookie with a 30-day lifetime. User and session data live in the reserved _cr_users, _cr_sessions, and _cr_email_tokens tables in your app's database — don't touch these directly (see Database).

Verification, reset, and 2FA emails are sent through env.EMAIL automatically — there's nothing to configure.