Email login

Email login provides a few capabilities for your SaaS application

  1. Provide email and password functionality for multitenant application
  2. Ability to reset password
  3. Verify user email

User Authentication with Next.js

Every application has users. This page introduces you to the basics of Nile's drop-in user management in the context of a Next.js application.

Sign up for an invite to Nile if you don't have one already and follow the prompts to create a workspace and database.

1. Clone the example application.

git clone https://github.com/niledatabase/niledatabase.git
cp -r niledatabase/examples/user_management/email_login/NextJS ./nile-email-login
cd nile-email-login

and install dependencies with yarn install or npm install.

2. Configure your application.

For database access, configure the Nile SDK with the necessary credentials:

  • Rename .env.local.example to .env.local in the project's root directory and open it.
  • Enter your database credentials (NILEDB_USER and NILEDB_PASSWORD). Use existing credentials, or generate new ones through the Nile Console:
  1. Visit the Nile Console, select your database, and navigate to Settings > Credentials.
  2. Click Generate credentials, then Generate and Copy credentials to clipboard.
  3. The copied credentials include two UUIDs: the first is the username and the second is the password, separated by a colon (":"). Paste the username into the NILEDB_USER value in .env.local, and the password into the NILEDB_PASSWORD value.

These credentials authenticate your app with the Nile API.

3. Run, sign up and query users.

Let's run the application to see things working, and then we'll look under the hood to see how they work.

  1. Run npm run dev, yarn dev, or pnpm dev to start the server.
  2. Open http://localhost:3000/sign-up.
  3. Enter an email address and password, and click Sign up.

If you're configuration is correct, you'll see the success response from the Nile API.

Login to the Nile Console, select your database, and open the SQL editor. Query your users table:

SELECT * FROM users.users;

You should see a record with your newly created user.

4. Dig Deeper

Let's walk through the sign-up flow, from front-end to back-end:

The SignUpForm

Open /app/sign-up/page.tsx to find a simple landing page that wraps a SignUp component:

import SignUp from "@/nile/ui/SignUpForm";

export default function SignUpPage() {
  return <SignUp />;
}

The SignUpForm (in /nile/ui/SignUpForm/index.tsx) provides some basic UI and a couple of key components:

  • The <NileContext> wrapper that provides configuration to nested components
  • The <UserSignupForm> from the Nile UI Kit
import { UserSignupForm } from '@niledatabase/react';
...

export default function SignUp() {
  const [res, setRes] = useState({});
  return (
    <NileContext>
      <Stack gap={2}>
        ...
        <UserSignupForm
          attributes={[
            ...
          ]}
          onSuccess={(response) => {
            push("/");
          }}
        />
        ...
      </Stack>
    </NileContext>
  );
}

The <UserSignupForm> calls an endpoint on your API with a payload containing signup details. That means your API server needs to handle the request. We'll look at that next.

Why do I need an API server? Because of restrictions around 3rd-party cookies and other security concerns, we recommend a dedicated API server on your domain that handles your business logic and makes requests to Nile. Plus it keeps Nile out of your user's view, and your application front and center.

The sign-up route

Open /app/api/sign-up/route.ts:

import { api } from "@/nile/Server";

export async function POST(req: Request) {
  const res = await api.auth.signUp(req);

  if (res && res.status >= 200 && res.status < 300) {
    const body = await res.json();
    return new Response(JSON.stringify(body), { status: 201 });
  } else {
    const body = await res.text();
    return new Response(body, { status: res.status });
  }
}

This API route delegates the request and response to the Nile SDK. If you ever need custom handling for requests or responses, you'd add that here.

The Nile SDK makes a request to our API, creating a user in your database and generating a JWT for the user that it returns in the response.

5. Login

With your application running, open http://localhost:3000/ and login with the user you created in Step 3.

This is implemented using the same pattern used for sign-up. Open /app/page.tsx to find the LoginForm used, which wraps the <UserLoginForm> from the Nile UI Kit. In /api/login/route.ts you'll again find the request and response delegated to the Nile SDK.

Summary

You've used the basic features of Nile's drop-in user management: user creation and authentication.

Next up: