#convex auth with password using next

10 messages · Page 1 of 1 (latest)

honest trenchBOT
#

Hi @junior flint. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

A 404 error on POST to /api/auth when using Convex Auth with password authentication in a Next.js app is a common issue, and several causes and solutions are documented:

Common Causes & Solutions

  1. Middleware Location in Next.js with src Directory

    • If you are using a src directory (e.g., src/app, src/components), your middleware.ts file must also be inside the src directory. If it's at the project root, Next.js won't register it, and /api/auth requests won't be proxied to Convex, resulting in a 404 error.
    • Solution: Move your middleware.ts into the src directory if your app structure uses it. This has resolved the issue for others in the same situation Discord: Convex auth failing when adding src directory.
  2. Missing or Incorrect Middleware

    • Convex Auth for Next.js relies on middleware to proxy /api/auth requests to Convex. If the middleware is missing, misconfigured, or not in the correct location, you'll get a 404.
    • Solution: Ensure you have the correct middleware set up as described in the Convex Auth docs. Here’s a typical example:
      import {
        convexAuthNextjsMiddleware,
        createRouteMatcher,
        nextjsMiddlewareRedirect,
      } from "@convex-dev/auth/nextjs/server";
      
      const isSignInPage = createRouteMatcher(["/signin"]);
      const isProtectedRoute = createRouteMatcher(["/", "/server"]);
      
      export default convexAuthNextjsMiddleware(async (request, { convexAuth }) => {
        if (isSignInPage(request) && (await convexAuth.isAuthenticated())) {
          return nextjsMiddlewareRedirect(request, "/");
        }
        if (isProtectedRoute(request) && !(await convexAuth.isAuthenticated())) {
          return nextjsMiddlewareRedirect(request, "/signin");
        }
      });
#

export const config = {
matcher: ["/((?!.\..|_next).)", "/", "/(api|trpc)(.)"],
};
```

  1. Monorepo or Custom Directory Structure

  2. General Debugging

    • If you’re still stuck, add verbose logging to your middleware to see what’s happening, and ensure you’re not missing any required steps from the Convex Auth setup guide Discord: Self Hosted Auth.

Summary

  • Move your middleware.ts into the src directory if you’re using one.
  • Ensure your middleware is set up and configured correctly.
  • Check that your routes are registered and your deployment is up to date.

If you follow these steps, the 404 on /api/auth should be resolved. If not, please share your project structure and middleware file for more targeted help.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@junior flint Kapa.ai is still learning and improving, please let me know how I did by reacting below.

#

Let me check the knowledge base for you again. One moment! :books:

#

Great to hear you solved the middleware issue!

For Convex Auth with password authentication, your users table schema can be customized to include any fields you want to collect during sign-up. At a minimum, you’ll want to store the user’s email. You can add more fields (like name, roles, etc.) as needed.

Here’s a typical example for a users table schema for password authentication:

import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
import { authTables } from "@convex-dev/auth/server";

export default defineSchema({
  ...authTables,
  users: defineTable({
    email: v.string(),
    name: v.optional(v.string()),
    // Add any additional fields you want:
    // role: v.optional(v.string()),
    // avatarUrl: v.optional(v.string()),
  }).index("email", ["email"]),
  // Your other tables...
});
  • If you want to add required fields, make sure your sign-up form and the profile callback in your Password provider return those fields, otherwise you’ll get schema validation errors.
  • If you want to add optional fields, use v.optional().

Important:
You can only make a field required if it is always provided during sign-up. If you make a field required but don’t provide it, you’ll get an error during user creation. Many developers start with fields as optional and make them required once their sign-up flow is finalized and always provides those fields Customizing Schema.

If you want to store additional fields from your sign-up form, you should also customize the profile method in your Password provider to return those fields. For example:

import { Password } from "@convex-dev/auth/providers/Password";
import { DataModel } from "./_generated/dataModel";
#

export default Password<DataModel>({
profile(params, ctx) {
return {
email: params.email as string,
name: params.name as string,
// Add other fields here
};
},
});

[Customize user information](<https://labs.convex.dev/auth/config/passwords#customize-user-information>)

**Summary:**  
- Start with `email: v.string()` in your users table.
- Add more fields as needed, using `v.optional()` for optional fields.
- Make sure your sign-up form and `profile` callback provide all required fields.

Let me know if you want an example with specific fields!
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
#

@junior flint Kapa.ai is still learning and improving, please let me know how I did by reacting below.

#

Let me check the knowledge base for you again. One moment! :books:

#

In Convex Auth, the user's password is not stored directly in your users table. Instead, password handling (including hashing and verification) is managed internally by the Convex Auth system when you use the Password provider.

When a user signs up or signs in, the password is processed by the Password provider, which by default uses Scrypt (from Lucia) to hash the password securely. You do not need to add a password field to your users table—Convex Auth manages password storage and verification in its own internal tables and logic. Your users table is for user profile data (like email, name, etc.), not for storing password hashes or secrets.

If you want to customize how passwords are hashed or verified, you can provide a crypto option in the Password provider config, but this is advanced usage. By default, Convex Auth handles this securely for you Password provider docs PasswordConfig options.

Summary:

  • You do not need a password field in your users table.
  • Passwords are handled, hashed, and verified internally by Convex Auth.
  • Your schema should focus on user profile fields (email, name, etc.).

If you want to see or customize password validation, you can do so via the validatePasswordRequirements option in the Password provider config, but the actual password storage is not exposed in your schema Customize sign-up form validation.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: