[GH-ISSUE #796] Invalid redirect for social logins, when deployed in docker compose on vps #8438

Closed
opened 2026-04-13 03:30:26 -05:00 by GiteaMirror · 12 comments
Owner

Originally created by @jabedzaman on GitHub (Dec 7, 2024).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/796

Describe the bug
When ran via docker compose on a vps, and tried to login with social providers then the redirect is invalid, and actually gets towards http://<container_id>:3000/

To Reproduce
Steps to reproduce the behavior:

  1. create a docker image for your app using better-auth for any social login
  2. ran the image via docker compose, in the same docker compose file also keep your nginx proxy manager
  3. try accessing the app via the domain added to it via the nginx proxy manager
  4. now try loggin in via any social provider

Expected behavior
A proper auth flow redirecting to my main website

Desktop (please complete the following information):

  • OS: debian (vps)
  • Browser: chrome

Additional context
My better auth client

import { createAuthClient } from "better-auth/react";

export const authClient = createAuthClient({});
import { betterAuth } from "better-auth";
import { mongodbAdapter } from "better-auth/adapters/mongodb";
import { mongo } from "~/db/mongo";

export const auth = betterAuth({
  trustedOrigins: ["https://store.com"],
  database: mongodbAdapter(mongo),
  emailAndPassword: {
    enabled: true,
  },
  socialProviders: {
    google: {
      clientId: process.env.GOOGLE_CLIENT_ID as string,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
    },
    github: {
      clientId: process.env.GITHUB_CLIENT_ID as string,
      clientSecret: process.env.GITHUB_CLIENT_SECRET as string,
    },
  },
});
// other code

<Button
          onClick={async () =>
            await authClient.signIn.social({
              provider: "github",
            })
          }
          variant="outline"
          type="button"
          disabled={loading}
        >
     Login
    </Button>
   // other code

nginx proxy manager settings:

image
Originally created by @jabedzaman on GitHub (Dec 7, 2024). Original GitHub issue: https://github.com/better-auth/better-auth/issues/796 **Describe the bug** When ran via docker compose on a vps, and tried to login with social providers then the redirect is invalid, and actually gets towards `http://<container_id>:3000/` **To Reproduce** Steps to reproduce the behavior: 1. create a docker image for your app using `better-auth` for any social login 2. ran the image via docker compose, in the same docker compose file also keep your nginx proxy manager 3. try accessing the app via the domain added to it via the nginx proxy manager 4. now try loggin in via any social provider **Expected behavior** A proper auth flow redirecting to my main website **Desktop (please complete the following information):** - OS: debian (vps) - Browser: chrome **Additional context** My better auth client ```src/lib/auth.client.ts import { createAuthClient } from "better-auth/react"; export const authClient = createAuthClient({}); ``` ```src/lib/auth.ts import { betterAuth } from "better-auth"; import { mongodbAdapter } from "better-auth/adapters/mongodb"; import { mongo } from "~/db/mongo"; export const auth = betterAuth({ trustedOrigins: ["https://store.com"], database: mongodbAdapter(mongo), emailAndPassword: { enabled: true, }, socialProviders: { google: { clientId: process.env.GOOGLE_CLIENT_ID as string, clientSecret: process.env.GOOGLE_CLIENT_SECRET as string, }, github: { clientId: process.env.GITHUB_CLIENT_ID as string, clientSecret: process.env.GITHUB_CLIENT_SECRET as string, }, }, }); ``` ```src/app/login/page.tsx // other code <Button onClick={async () => await authClient.signIn.social({ provider: "github", }) } variant="outline" type="button" disabled={loading} > Login </Button> // other code ``` nginx proxy manager settings: <img width="570" alt="image" src="https://github.com/user-attachments/assets/8dc6f8aa-31bc-45b0-9b78-e568cfc42e69">
GiteaMirror added the locked label 2026-04-13 03:30:26 -05:00
Author
Owner

@Bekacru commented on GitHub (Dec 7, 2024):

have you set BETTER_AUTH_URL to your production url in your .env?

<!-- gh-comment-id:2524955499 --> @Bekacru commented on GitHub (Dec 7, 2024): have you set `BETTER_AUTH_URL` to your production url in your .env?
Author
Owner

@jabedzaman commented on GitHub (Dec 7, 2024):

done but one issue persists!!

image

and this happens only on the first login... later doesnt happens

<!-- gh-comment-id:2525077897 --> @jabedzaman commented on GitHub (Dec 7, 2024): done but one issue persists!! ![image](https://github.com/user-attachments/assets/796d5ceb-9b15-4411-ad9b-19ab99f7eb59) and this happens only on the first login... later doesnt happens
Author
Owner

@jabedzaman commented on GitHub (Dec 9, 2024):

@Bekacru 🫠??

<!-- gh-comment-id:2527412994 --> @jabedzaman commented on GitHub (Dec 9, 2024): @Bekacru 🫠??
Author
Owner

@Bekacru commented on GitHub (Dec 9, 2024):

make sure you have verification table and that the verification table has expiresAt field which data type should be timestamp or similar data type that can store both date and time

<!-- gh-comment-id:2527503104 --> @Bekacru commented on GitHub (Dec 9, 2024): make sure you have `verification` table and that the verification table has `expiresAt` field which data type should be timestamp or similar data type that can store both date and time
Author
Owner

@jabedzaman commented on GitHub (Dec 9, 2024):

here is my schema.prisma

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "mongodb"
  url      = env("DATABASE_URL")
}

enum Role {
  USER
  ADMIN
}

model User {
  id            String    @id @default(auto()) @map("_id") @db.ObjectId
  email         String    @unique
  name          String?
  emailVerified Boolean
  image         String?
  role          Role[]    @default([USER])
  createdAt     DateTime
  updatedAt     DateTime
  products      Product[]
  sessions      Session[]
  accounts      Account[]
  orders        Order[]

  @@map("user")
}

model Session {
  id        String   @id @map("_id")
  expiresAt DateTime
  token     String
  createdAt DateTime
  updatedAt DateTime
  ipAddress String?
  userAgent String?
  userId    String   @db.ObjectId
  user      User     @relation(fields: [userId], references: [id], onDelete: Cascade)

  @@unique([token])
  @@map("session")
}

model Account {
  id                    String    @id @map("_id")
  accountId             String
  providerId            String
  userId                String    @db.ObjectId
  user                  User      @relation(fields: [userId], references: [id], onDelete: Cascade)
  accessToken           String?
  refreshToken          String?
  idToken               String?
  accessTokenExpiresAt  DateTime?
  refreshTokenExpiresAt DateTime?
  scope                 String?
  password              String?
  createdAt             DateTime
  updatedAt             DateTime

  @@map("account")
}

model Verification {
  id         String    @id @map("_id")
  identifier String
  value      String
  expiresAt  DateTime
  createdAt  DateTime?
  updatedAt  DateTime?

  @@map("verification")
}
 "prisma": "^6.0.1",
  "mongodb": "^6.11.0",
  "better-auth": "^1.0.10",
<!-- gh-comment-id:2527988034 --> @jabedzaman commented on GitHub (Dec 9, 2024): here is my `schema.prisma` ``` generator client { provider = "prisma-client-js" } datasource db { provider = "mongodb" url = env("DATABASE_URL") } enum Role { USER ADMIN } model User { id String @id @default(auto()) @map("_id") @db.ObjectId email String @unique name String? emailVerified Boolean image String? role Role[] @default([USER]) createdAt DateTime updatedAt DateTime products Product[] sessions Session[] accounts Account[] orders Order[] @@map("user") } model Session { id String @id @map("_id") expiresAt DateTime token String createdAt DateTime updatedAt DateTime ipAddress String? userAgent String? userId String @db.ObjectId user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@unique([token]) @@map("session") } model Account { id String @id @map("_id") accountId String providerId String userId String @db.ObjectId user User @relation(fields: [userId], references: [id], onDelete: Cascade) accessToken String? refreshToken String? idToken String? accessTokenExpiresAt DateTime? refreshTokenExpiresAt DateTime? scope String? password String? createdAt DateTime updatedAt DateTime @@map("account") } model Verification { id String @id @map("_id") identifier String value String expiresAt DateTime createdAt DateTime? updatedAt DateTime? @@map("verification") } ``` ``` "prisma": "^6.0.1", "mongodb": "^6.11.0", "better-auth": "^1.0.10", ```
Author
Owner

@jabedzaman commented on GitHub (Dec 15, 2024):

@Bekacru ?

<!-- gh-comment-id:2543442438 --> @jabedzaman commented on GitHub (Dec 15, 2024): @Bekacru ?
Author
Owner

@svaraborut commented on GitHub (Dec 16, 2024):

The first issue was due to baseUrl being missingo or miss-configured. Now the issue is completely unrelated as the embedded error page is properly reached after redirect. Please provide your current configuration and also a stack trace from the container. Make also sure you have configured the OAuth2 provider (Google and GitHub) to accept the provided redirect url.

<!-- gh-comment-id:2544585443 --> @svaraborut commented on GitHub (Dec 16, 2024): The first issue was due to `baseUrl` being missingo or miss-configured. Now the issue is completely unrelated as the embedded error page is properly reached after redirect. Please provide your current configuration and also a stack trace from the container. Make also sure you have configured the OAuth2 provider (Google and GitHub) to accept the provided redirect url.
Author
Owner

@jabedzaman commented on GitHub (Dec 17, 2024):

here is my auth config file:

import { render } from "@react-email/components";
import { betterAuth } from "better-auth";
import { mongodbAdapter } from "better-auth/adapters/mongodb";
import { HOME_DOMAIN } from "~/constants";
import { mongo } from "~/db/mongo";
import { sendEmail } from "~/emails";
import { forgotPassEmail } from "~/emails/templates";

export const auth = betterAuth({
  trustedOrigins: [HOME_DOMAIN],
  database: mongodbAdapter(mongo),
  emailAndPassword: {
    enabled: true,
    autoSignIn: true,
    sendResetPassword: async ({ user, url }) => {
      const html = await render(forgotPassEmail({ url }));
      await sendEmail(user.email, "Password Reset Request", html);
    },
  },
  socialProviders: {
    google: {
      clientId: process.env.GOOGLE_CLIENT_ID as string,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
    },
    github: {
      clientId: process.env.GITHUB_CLIENT_ID as string,
      clientSecret: process.env.GITHUB_CLIENT_SECRET as string,
    },
  },
});

Is it required to pass the redirect uri to the auth.socialProviders ??? Also this issue when we try to login (i.e. new account auto create) for the first time

<!-- gh-comment-id:2547465341 --> @jabedzaman commented on GitHub (Dec 17, 2024): here is my auth config file: ```tsx import { render } from "@react-email/components"; import { betterAuth } from "better-auth"; import { mongodbAdapter } from "better-auth/adapters/mongodb"; import { HOME_DOMAIN } from "~/constants"; import { mongo } from "~/db/mongo"; import { sendEmail } from "~/emails"; import { forgotPassEmail } from "~/emails/templates"; export const auth = betterAuth({ trustedOrigins: [HOME_DOMAIN], database: mongodbAdapter(mongo), emailAndPassword: { enabled: true, autoSignIn: true, sendResetPassword: async ({ user, url }) => { const html = await render(forgotPassEmail({ url })); await sendEmail(user.email, "Password Reset Request", html); }, }, socialProviders: { google: { clientId: process.env.GOOGLE_CLIENT_ID as string, clientSecret: process.env.GOOGLE_CLIENT_SECRET as string, }, github: { clientId: process.env.GITHUB_CLIENT_ID as string, clientSecret: process.env.GITHUB_CLIENT_SECRET as string, }, }, }); ``` Is it required to pass the redirect uri to the `auth.socialProviders` ??? Also this issue when we try to login (i.e. new account auto create) for the first time
Author
Owner

@Bekacru commented on GitHub (Dec 17, 2024):

The "state not found" issue only occurs when the provider does not return the state parameter in the callback. this typically happens if the state wasn’t sent in the first place. try passing disableRedirect to signIn.social and check whether the URL returned from signIn.social includes the state parameter. Let me know what you find

<!-- gh-comment-id:2547661907 --> @Bekacru commented on GitHub (Dec 17, 2024): The "state not found" issue only occurs when the provider does not return the state parameter in the callback. this typically happens if the state wasn’t sent in the first place. try passing `disableRedirect` to `signIn.social` and check whether the URL returned from `signIn.social` includes the state parameter. Let me know what you find
Author
Owner

@moshetanzer commented on GitHub (Mar 25, 2025):

Hey @javawizard

Did you manage to solve this?

<!-- gh-comment-id:2752132946 --> @moshetanzer commented on GitHub (Mar 25, 2025): Hey @javawizard Did you manage to solve this?
Author
Owner

@Kinfe123 commented on GitHub (Apr 11, 2025):

make sure the verification table exists and inspect if it has a some state stored there post the error

<!-- gh-comment-id:2796720502 --> @Kinfe123 commented on GitHub (Apr 11, 2025): make sure the verification table exists and inspect if it has a some state stored there post the error
Author
Owner

@jabedzaman commented on GitHub (Apr 12, 2025):

Hey @javawizard

Did you manage to solve this?

passing: disableRedirect fixed it for me

<!-- gh-comment-id:2798926309 --> @jabedzaman commented on GitHub (Apr 12, 2025): > Hey [@javawizard](https://github.com/javawizard) > > Did you manage to solve this? passing: `disableRedirect` fixed it for me
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#8438