[GH-ISSUE #4089] Feature Request: Anonymous User Per IP #9825

Open
opened 2026-04-13 05:34:19 -05:00 by GiteaMirror · 6 comments
Owner

Originally created by @bestickley on GitHub (Aug 19, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/4089

Originally assigned to: @jonathansamines on GitHub.

Is this suited for github?

  • Yes, this is suited for github

Is your feature request related to a problem? Please describe.

No response

Describe the solution you'd like

I want only 1 anonymous user created per IP. I'd like a callback function to generateId of anonymous user where I can access request object (IP address) and then Anonymous Plugin will check if that id already exists in DB.

Describe alternatives you've considered

Using hooks

Additional context

No response

Originally created by @bestickley on GitHub (Aug 19, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/4089 Originally assigned to: @jonathansamines on GitHub. ### Is this suited for github? - [x] Yes, this is suited for github ### Is your feature request related to a problem? Please describe. _No response_ ### Describe the solution you'd like I want only 1 anonymous user created per IP. I'd like a callback function to `generateId` of anonymous user where I can access request object (IP address) and then Anonymous Plugin will check if that id already exists in DB. ### Describe alternatives you've considered Using hooks ### Additional context _No response_
GiteaMirror added the credentials label 2026-04-13 05:34:19 -05:00
Author
Owner

@bestickley commented on GitHub (Aug 20, 2025):

Here is the pnpm patch I'm currently using to get around this issue:

diff --git a/dist/plugins/anonymous/index.d.ts b/dist/plugins/anonymous/index.d.ts
index 1511aff6527d44c472b18295199fcbf61362db6b..c1b5b8b4acaad9c1eacbf9f35a0b867e49a46b6a 100644
--- a/dist/plugins/anonymous/index.d.ts
+++ b/dist/plugins/anonymous/index.d.ts
@@ -39,6 +39,15 @@ interface AnonymousOptions {
      * Disable deleting the anonymous user after linking
      */
     disableDeleteAnonymousUser?: boolean;
+    /**
+     * A hook to generate an email for the anonymous user. If specified, the
+     * plugin will check to see if an anonymous user with this email already
+     * exists and if so, will re-use that anonymous user. Useful for per IP
+     * anonymous users.
+     */
+    generateEmail?: (ctx: EndpointContext<"/sign-in/anonymous", {
+        method: "POST";
+    }, AuthContext>) => Promise<string> | string;
     /**
      * A hook to generate a name for the anonymous user.
      * Useful if you want to have random names for anonymous users, or if `name` is unique in your database.
diff --git a/dist/plugins/anonymous/index.mjs b/dist/plugins/anonymous/index.mjs
index aa174bb6b3fcd9fe5f2e304119f6f2fe03cb75cc..11750262ec0a29396c9562bc9d0a4dc818139843 100644
--- a/dist/plugins/anonymous/index.mjs
+++ b/dist/plugins/anonymous/index.mjs
@@ -80,19 +80,26 @@ const anonymous = (options) => {
         async (ctx) => {
           const { emailDomainName = getOrigin(ctx.context.baseURL) } = options || {};
           const id = generateId();
-          const email = `temp-${id}@${emailDomainName}`;
+          const email = await options?.generateEmail?.(ctx) || `temp-${id}@${emailDomainName}`;
           const name = await options?.generateName?.(ctx) || "Anonymous";
-          const newUser = await ctx.context.internalAdapter.createUser(
-            {
-              email,
-              emailVerified: false,
-              isAnonymous: true,
-              name,
-              createdAt: /* @__PURE__ */ new Date(),
-              updatedAt: /* @__PURE__ */ new Date()
-            },
-            ctx
-          );
+          let newUser
+          if (options?.generateEmail) {
+            const res = await ctx.context.internalAdapter.findUserByEmail(email);
+            newUser = res?.user;
+          }
+          if (!newUser) {
+            newUser = await ctx.context.internalAdapter.createUser(
+              {
+                email,
+                emailVerified: false,
+                isAnonymous: true,
+                name,
+                createdAt: /* @__PURE__ */ new Date(),
+                updatedAt: /* @__PURE__ */ new Date()
+              },
+              ctx
+            );
+          }
           if (!newUser) {
             throw ctx.error("INTERNAL_SERVER_ERROR", {
               message: ERROR_CODES.FAILED_TO_CREATE_USER

I'd prefer not to patch and to create my own plugin in userland but several of the cookie/session helpers used in the anonymous plugin are not exported so I found myself having to copy and paste a lot of code outside the library (i.e. setSessionCookie). If those could be exported that would be great.

Also, I'm not 100% sold on API design above. I'm not sure if there should be separate parameter in AnonymousOptions that specifies whether the code checks to see if user already exists. Would appreciate someone from core team's perspective on this.

<!-- gh-comment-id:3205238960 --> @bestickley commented on GitHub (Aug 20, 2025): Here is the pnpm patch I'm currently using to get around this issue: ```patch diff --git a/dist/plugins/anonymous/index.d.ts b/dist/plugins/anonymous/index.d.ts index 1511aff6527d44c472b18295199fcbf61362db6b..c1b5b8b4acaad9c1eacbf9f35a0b867e49a46b6a 100644 --- a/dist/plugins/anonymous/index.d.ts +++ b/dist/plugins/anonymous/index.d.ts @@ -39,6 +39,15 @@ interface AnonymousOptions { * Disable deleting the anonymous user after linking */ disableDeleteAnonymousUser?: boolean; + /** + * A hook to generate an email for the anonymous user. If specified, the + * plugin will check to see if an anonymous user with this email already + * exists and if so, will re-use that anonymous user. Useful for per IP + * anonymous users. + */ + generateEmail?: (ctx: EndpointContext<"/sign-in/anonymous", { + method: "POST"; + }, AuthContext>) => Promise<string> | string; /** * A hook to generate a name for the anonymous user. * Useful if you want to have random names for anonymous users, or if `name` is unique in your database. diff --git a/dist/plugins/anonymous/index.mjs b/dist/plugins/anonymous/index.mjs index aa174bb6b3fcd9fe5f2e304119f6f2fe03cb75cc..11750262ec0a29396c9562bc9d0a4dc818139843 100644 --- a/dist/plugins/anonymous/index.mjs +++ b/dist/plugins/anonymous/index.mjs @@ -80,19 +80,26 @@ const anonymous = (options) => { async (ctx) => { const { emailDomainName = getOrigin(ctx.context.baseURL) } = options || {}; const id = generateId(); - const email = `temp-${id}@${emailDomainName}`; + const email = await options?.generateEmail?.(ctx) || `temp-${id}@${emailDomainName}`; const name = await options?.generateName?.(ctx) || "Anonymous"; - const newUser = await ctx.context.internalAdapter.createUser( - { - email, - emailVerified: false, - isAnonymous: true, - name, - createdAt: /* @__PURE__ */ new Date(), - updatedAt: /* @__PURE__ */ new Date() - }, - ctx - ); + let newUser + if (options?.generateEmail) { + const res = await ctx.context.internalAdapter.findUserByEmail(email); + newUser = res?.user; + } + if (!newUser) { + newUser = await ctx.context.internalAdapter.createUser( + { + email, + emailVerified: false, + isAnonymous: true, + name, + createdAt: /* @__PURE__ */ new Date(), + updatedAt: /* @__PURE__ */ new Date() + }, + ctx + ); + } if (!newUser) { throw ctx.error("INTERNAL_SERVER_ERROR", { message: ERROR_CODES.FAILED_TO_CREATE_USER ``` I'd prefer not to patch and to create my own plugin in userland but several of the cookie/session helpers used in the anonymous plugin are not exported so I found myself having to copy and paste a lot of code outside the library (i.e. `setSessionCookie`). If those could be exported that would be great. Also, I'm not 100% sold on API design above. I'm not sure if there should be separate parameter in `AnonymousOptions` that specifies whether the code checks to see if user already exists. Would appreciate someone from core team's perspective on this.
Author
Owner

@dosubot[bot] commented on GitHub (Nov 19, 2025):

Hi, @bestickley. I'm Dosu, and I'm helping the better-auth team manage their backlog and am marking this issue as stale.

Issue Summary:

  • You requested a feature to limit anonymous users to one per IP by adding a callback in the generateId method to check existing IDs.
  • You shared a pnpm patch introducing a generateEmail hook to enable anonymous user reuse by email, effectively supporting per-IP anonymous user reuse.
  • You encountered difficulties creating a custom plugin due to unexported cookie/session helpers like setSessionCookie.
  • You are seeking input from the core team on the API design and whether a separate option should control user existence checks.
  • The issue remains unresolved with no recent updates.

Next Steps:

  • Please let me know if this feature is still relevant to the latest version of better-auth by commenting on this issue.
  • If I do not hear back within 7 days, I will automatically close this issue.

Thank you for your understanding and contribution!

<!-- gh-comment-id:3553558823 --> @dosubot[bot] commented on GitHub (Nov 19, 2025): Hi, @bestickley. I'm [Dosu](https://dosu.dev), and I'm helping the better-auth team manage their backlog and am marking this issue as stale. **Issue Summary:** - You requested a feature to limit anonymous users to one per IP by adding a callback in the `generateId` method to check existing IDs. - You shared a pnpm patch introducing a `generateEmail` hook to enable anonymous user reuse by email, effectively supporting per-IP anonymous user reuse. - You encountered difficulties creating a custom plugin due to unexported cookie/session helpers like `setSessionCookie`. - You are seeking input from the core team on the API design and whether a separate option should control user existence checks. - The issue remains unresolved with no recent updates. **Next Steps:** - Please let me know if this feature is still relevant to the latest version of better-auth by commenting on this issue. - If I do not hear back within 7 days, I will automatically close this issue. Thank you for your understanding and contribution!
Author
Owner

@bestickley commented on GitHub (Nov 20, 2025):

Still relevant

<!-- gh-comment-id:3555455626 --> @bestickley commented on GitHub (Nov 20, 2025): Still relevant
Author
Owner

@dosubot[bot] commented on GitHub (Feb 19, 2026):

Hi, @bestickley. I'm Dosu, and I'm helping the better-auth team manage their backlog and am marking this issue as stale.

Issue Summary:

  • You requested a feature to limit anonymous users to one per IP by adding a generateEmail hook that checks for existing users and reuses them.
  • You shared a pnpm patch implementing this feature.
  • You encountered difficulties creating a custom plugin due to unexported cookie/session helpers like setSessionCookie.
  • You sought input from the core team on the API design.
  • The issue remains open with no further updates after you confirmed it is still relevant.

Next Steps:

  • Please let me know if this issue is still relevant to the latest version of better-auth by commenting here to keep the discussion open.
  • Otherwise, this issue will be automatically closed in 7 days.

Thank you for your understanding and contribution!

<!-- gh-comment-id:3928271558 --> @dosubot[bot] commented on GitHub (Feb 19, 2026): Hi, @bestickley. I'm [Dosu](https://dosu.dev), and I'm helping the better-auth team manage their backlog and am marking this issue as stale. **Issue Summary:** - You requested a feature to limit anonymous users to one per IP by adding a generateEmail hook that checks for existing users and reuses them. - You shared a pnpm patch implementing this feature. - You encountered difficulties creating a custom plugin due to unexported cookie/session helpers like setSessionCookie. - You sought input from the core team on the API design. - The issue remains open with no further updates after you confirmed it is still relevant. **Next Steps:** - Please let me know if this issue is still relevant to the latest version of better-auth by commenting here to keep the discussion open. - Otherwise, this issue will be automatically closed in 7 days. Thank you for your understanding and contribution!
Author
Owner

@bestickley commented on GitHub (Feb 26, 2026):

still relevant, 6 upvotes

<!-- gh-comment-id:3967636768 --> @bestickley commented on GitHub (Feb 26, 2026): still relevant, 6 upvotes
Author
Owner

@dosubot[bot] commented on GitHub (Feb 26, 2026):

@Bekacru The user bestickley has indicated that this issue is still relevant and has 6 upvotes despite being closed as stale. Could you please take a look and assist?

<!-- gh-comment-id:3967650721 --> @dosubot[bot] commented on GitHub (Feb 26, 2026): @Bekacru The user bestickley has indicated that this issue is still relevant and has 6 upvotes despite being closed as stale. Could you please take a look and assist?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#9825