JavaScript Backend Integration

Learn how to integrate Nile Auth with any JavaScript backend framework.

It is important to note that the Auth service is designed to work with actions a user would take, it is not an exhaustive list of actions a developer or super user could take.

Overview

This guide covers the general principles of integrating Nile Auth with any JavaScript backend framework.

Installation

npm install @niledatabase/server

Core Concepts

Nile Instance

A configured Nile instance handles proxying requests to the Nile Auth API. Your client connects to your server, which then formats and ensures the requests can be handled by the Nile Auth API.

The SDK is designed to make clients talking through your server to the Nile auth service as transparent as possible.

In addition, you can use the SDK to directly access the Nile Auth API from your server.

Authentication Flow

1. User Initiates Authentication

  • The user clicks a “Sign in” button.
  • This action triggers a signIn method with the chosen provider. Your server handles all requests, which in most cases is simply forwarding them on to the Nile auth service with some additional information to help identify the client.

2. Redirect to Provider (OAuth Flow)

  • If an OAuth provider (e.g., Google, GitHub) is used, the user is redirected to the provider’s authentication page. This works by Nile auth returning redirects to your application, which the SDK handles in order to send the user to the provider.
  • The user enters their credentials and grants permission to the application. Because your server is handling the requests, the user is redirected back to your application.

3. Provider Callback & Token Exchange

  • After successful authentication, the provider redirects the user back to your application, which proxies the request to the Nile auth service.
  • Nile auth exchanges the authorization code for an access token and forwards the authorization information to your server, which in turn would just pass that on to the client.

4. Session Creation

  • Via your service, nile auth provides a secure cookie.
  • The cookie includes basic user information, which can be accessed using the nile.api.auth.getSession or a full user profile via nile.api.auth.me

5. Accessing the Session

  • A session is always within the context of a request. You can access session data using:
import http from "http";
import { Nile } from "@niledatabase/server";

const nile = await Nile();

const server = http.createServer(async (req, res) => {
  const session = nile.api.auth.getSession(req);
  // or const session = nile.api.auth.getSession(new Headers('cookie', req.headers.cookie));
  if (session) {
    console.log("User is authenticated", session.user);
  });
)}

A Nile auth application server must respond to API requests. To see a full list of available API routes, check out the API Reference.

User Management

While user signup, authentication and even user profile UI is handled automatically by the built-in routes and UI components, you can use the SDK to directly call user management APIs in Nile Auth.

For example, to login a user with email and password, you can use the following code:

login
try {
    const loginBody = {
        email: 'test@test.com',
        password: 'password'
    }
    debug(`logging in using ${loginBody.email} ${loginBody.password}`);
    await nile.api.login(loginBody);
  } catch (err) {
    console.error("Failed to login", err);
    return err;
  }

This will set nile.token to the user’s session token, which you can use to make authenticated requests to the Nile Auth API.

You can get the user’s profile information by calling the me API:

me
const user = await nile.api.users.me();
console.log(user);

You can also create a new user by calling the create API:

create
const user = await nile.api.users.create({
    email: 'test@test.com',
    password: 'password'
});

Or create a user in a specific tenant by setting tenantId before creating the user:

create-tenant
nile.tenantId = '8fa00d5e-ffa3-4662-96b0-bb8499b1cb68';
const user = await nile.api.users.createTenantUser({
    email: 'test@test.com',
    password: 'password'
});

You can also update a user’s profile information by calling the update API:

update
   const update = {
      name: 'updatedName',
    };
    const updatedUser = await nile.api.users.updateMe(update);
    console.log(updatedFirstUser);

Tenant Management

Nile Auth supports multi-tenancy out of the box and includes tenant management APIs. You can create a new tenant by calling the createTenant API:

create-tenant
const tenant = await nile.api.tenants.create({
    name: 'tenantName'
});

You rename a tenant by calling the updateTenant API after setting the tenantId to the tenant you want to update:

update-tenant
nile.tenantId = '8fa00d5e-ffa3-4662-96b0-bb8499b1cb68';
const tenant = await nile.api.tenants.updateTenant({
    name: 'newTenantName'
});

You can list the users in a tenant by calling the listUsers API after setting the tenantId to the tenant you want to list users from:

list-users
nile.tenantId = '8fa00d5e-ffa3-4662-96b0-bb8499b1cb68';
const users = await nile.api.tenants.listUsers();
console.log(users);

You can mark a tenant as deleted by calling the deleteTenant API after setting the tenantId to the tenant you want to delete:

delete-tenant
nile.tenantId = '8fa00d5e-ffa3-4662-96b0-bb8499b1cb68';
await nile.api.tenants.deleteTenant();

You can add users to a tenant and remove them by calling linkUser and unlinkUser APIs:

link-user
nile.tenantId = '8fa00d5e-ffa3-4662-96b0-bb8499b1cb68';
await nile.api.tenants.linkUser({
    userId: '123'
});
await nile.api.tenants.unlinkUser({
    userId: '123'
});

API Authentication

To authenticate API requests, you can use the session token:

const server = http.createServer(async (req, res) => {
  // Verify the session from the request
  const session = nile.api.auth.getSession(req);
  if (!session) {
    res.writeHead(401);
    res.end('Unauthorized');
    return;
  }
  
  // Process authenticated request
  // ...
});

Security Considerations

  • Never log or otherwise store user passwords in plain text
  • Never log or store authentication tokens or session information
  • Always validate and sanitize user input before passing it to Nile Auth APIs
  • Avoid exposing detailed error messages to clients that might reveal system information
  • Implement rate limiting for authentication attempts to prevent brute force attacks
  • Log authentication failures and suspicious activities for monitoring
  • Implement appropriate error responses that don’t leak sensitive information
  • Keep your Nile SDK and dependencies up to date

Framework-Specific Guides

Best Practices

  1. Error Handling Implement comprehensive error handling for all authentication flows. Return user-friendly error messages while logging detailed errors server-side. Use try-catch blocks around all authentication operations.

  2. Session Management Regularly validate sessions. Implement proper session cleanup on logout. Use secure session storage methods.

  3. Code Organization Separate authentication logic into dedicated middleware. Create reusable authentication utilities. Keep configuration in environment variables.

  4. Testing Test authentication flows thoroughly. Include both success and failure scenarios. Mock external authentication providers in tests.

Troubleshooting

Common Issues

  1. Invalid Session Token Verify that user authentication was successful. Verify the token is being properly passed in requests. Check if the session has expired. Ensure the token format is correct.

  2. CORS Issues Ensure your server is configured to accept requests from your client domain. Check that necessary CORS headers are being set.

  3. User Creation Failures Make sure you properly handle common user mistakes: Validate email format before submission and check for duplicate email address error that may be returned.

Debug Tips

  1. Enable debug logging:
const nile = new Nile({
  debug: true  // Enable detailed logging
});
  1. Monitor network requests in your browser’s developer tools
  2. Check server logs for detailed error messages
  3. Verify environment variables are properly set

For additional support, visit our Discord community or GitHub discussions.

Was this page helpful?