[GH-ISSUE #2524] nextCookies() didn't set twofactor cookies on auth.api.signInEmail #9239

Closed
opened 2026-04-13 04:39:34 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @aow3xm on GitHub (May 3, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/2524

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

I can't sign in user with twoFactor enabled with auth.api.signInEmail because twoFactor cookies aren't set for the user on the client side, and if I try to verify Totp at /2fa with authClient.twoFactor.verifyTotp, I'll get APIError with code 'INVALID_TWO_FACTOR_COOKIES', though if the user doesn't enable twoFactor by default, The user can still log in as expected, so is there a way to do that in server-actions, or do I have to move signIn back to the client with authClient.signIn? And I also looked on the docs in the twoFactor plugin, but it doesn't mention this

Current vs. Expected behavior

actions/login.ts

'use server';

import { routePaths } from '@/configs/page';
import { auth } from '@/lib/auth';
import { actionClient } from '@/lib/safe-action';
import { loginSchema } from '@/lib/schema/auth';
import { redirect } from 'next/navigation';

type WithTwoFactorResponse = Awaited<ReturnType<typeof auth.api.signInEmail>> & {
  twoFactorRedirect?: boolean;
};
export const loginUser = actionClient.schema(loginSchema)
  .action(async ({ parsedInput: { email, password } }) => {
    try {
      const response = (await auth.api.signInEmail({
        body: {
          email,
          password,
        },
      })) as WithTwoFactorResponse;
      if (response.twoFactorRedirect) {
        redirect(routePaths.twoFactor);
      }
      redirect(routePaths.personal.index);
    } catch (error) {
      throw error;
    }
});

What version of Better Auth are you using?

1.2.7

Provide environment information

OS: Windows 11
Browser: Edge
Framework: Nextjs 15.3.1

Which area(s) are affected? (Select all that apply)

Client

Auth config (if applicable)

auth.ts
import { nextCookies } from 'better-auth/next-js';
import { admin, createAuthMiddleware, twoFactor } from 'better-auth/plugins';
...
{
    plugins: [nextCookies(), admin(), twoFactor()]
}

Additional context

No response

Originally created by @aow3xm on GitHub (May 3, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/2524 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce I can't sign in user with twoFactor enabled with auth.api.signInEmail because twoFactor cookies aren't set for the user on the client side, and if I try to verify Totp at `/2fa` with authClient.twoFactor.verifyTotp, I'll get APIError with code `'INVALID_TWO_FACTOR_COOKIES'`, though if the user doesn't enable twoFactor by default, The user can still log in as expected, so is there a way to do that in server-actions, or do I have to move signIn back to the client with authClient.signIn? And I also looked on the docs in the twoFactor plugin, but it doesn't mention this ### Current vs. Expected behavior ``` actions/login.ts 'use server'; import { routePaths } from '@/configs/page'; import { auth } from '@/lib/auth'; import { actionClient } from '@/lib/safe-action'; import { loginSchema } from '@/lib/schema/auth'; import { redirect } from 'next/navigation'; type WithTwoFactorResponse = Awaited<ReturnType<typeof auth.api.signInEmail>> & { twoFactorRedirect?: boolean; }; export const loginUser = actionClient.schema(loginSchema) .action(async ({ parsedInput: { email, password } }) => { try { const response = (await auth.api.signInEmail({ body: { email, password, }, })) as WithTwoFactorResponse; if (response.twoFactorRedirect) { redirect(routePaths.twoFactor); } redirect(routePaths.personal.index); } catch (error) { throw error; } }); ``` ### What version of Better Auth are you using? 1.2.7 ### Provide environment information ```bash OS: Windows 11 Browser: Edge Framework: Nextjs 15.3.1 ``` ### Which area(s) are affected? (Select all that apply) Client ### Auth config (if applicable) ```typescript auth.ts import { nextCookies } from 'better-auth/next-js'; import { admin, createAuthMiddleware, twoFactor } from 'better-auth/plugins'; ... { plugins: [nextCookies(), admin(), twoFactor()] } ``` ### Additional context _No response_
GiteaMirror added the locked label 2026-04-13 04:39:34 -05:00
Author
Owner

@mmstroik commented on GitHub (May 5, 2025):

I don't use server actions, but in your config have you tried moving the nextCookies() plugin to be the last plugin in the array? There is a comment in the example in the docs that says to do that.

<!-- gh-comment-id:2849627505 --> @mmstroik commented on GitHub (May 5, 2025): I don't use server actions, but in your config have you tried moving the nextCookies() plugin to be the last plugin in the array? There is a comment in the example in the [docs](https://www.better-auth.com/docs/integrations/next#server-action-cookies) that says to do that.
Author
Owner

@aow3xm commented on GitHub (May 5, 2025):

I don't use server actions, but in your config have you tried moving the nextCookies() plugin to be the last plugin in the array? There is a comment in the example in the docs that says to do that.

well yes, it was my mistake, after moving the nextCookies() plugin to the end, it finally worked, thank you

<!-- gh-comment-id:2849690698 --> @aow3xm commented on GitHub (May 5, 2025): > I don't use server actions, but in your config have you tried moving the nextCookies() plugin to be the last plugin in the array? There is a comment in the example in the [docs](https://www.better-auth.com/docs/integrations/next#server-action-cookies) that says to do that. well yes, it was my mistake, after moving the nextCookies() plugin to the end, it finally worked, thank you
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#9239