Documentação
Comece a construirQuickstarts por frameworkExpress

Express

Um middleware que autentica e outro que autoriza.

Dois middlewares cobrem quase tudo: um que rejeita um token inválido e outro que rejeita quem não tem o papel. A página do Node explica o que eles chamam por baixo.

Instalação

npm install @nulvless/nulvless-js express

Crie o client

lib/nulvless.ts
import { createServerClient } from '@nulvless/nulvless-js';

export const nulvless = createServerClient(
  process.env.NULVLESS_URL!,
  process.env.NULVLESS_SECRET!,
);

Autenticação

middleware/auth.ts
import type { NextFunction, Request, Response } from 'express';
import { nulvless } from '../lib/nulvless';

export async function requireAuth(req: Request, res: Response, next: NextFunction) {
  const token = req.headers.authorization?.replace('Bearer ', '');
  if (!token) return res.status(401).end();

  const { data, error } = await nulvless.auth.verify(undefined, {
    headers: { Authorization: `Bearer ${token}` },
  });

  if (error) return res.status(401).end();

  req.session = data.session;
  req.userId = data.user.id;
  next();
}

Tipe a requisição

Para req.userId não ser um erro no TypeScript:

types/express.d.ts
import type { Session } from '@nulvless/nulvless-js';

declare global {
  namespace Express {
    interface Request {
      session?: Session;
      userId?: string;
    }
  }
}

Autorização

A mesma chamada, com a pergunta incluída — sem uma segunda ida ao servidor.

export function requireRole(roles: string[]) {
  return async (req: Request, res: Response, next: NextFunction) => {
    const token = req.headers.authorization?.replace('Bearer ', '');

    const { error } = await nulvless.auth.verify(
      { resource: req.params.org, roles },
      { headers: { Authorization: `Bearer ${token}` } },
    );

    if (error) return res.status(403).end();
    next();
  };
}

app.delete('/orgs/:org/keys/:id', requireRole(['owner', 'admin']), handler);

requireRole também verifica o token, então funciona sozinho. Empilhe depois de requireAuth só quando o handler também precisar de req.userId.

Aja em nome do usuário

import { forwardUserHeaders } from '@nulvless/nulvless-js';

app.post('/orgs/:org/invites', requireAuth, async (req, res) => {
  const { data, error } = await nulvless.auth.grants.invite(
    { invites: [{ email: req.body.email, role_id: req.body.role_id }], resource: req.params.org },
    { headers: forwardUserHeaders(req) },
  );

  if (error) return res.status(400).json({ error });
  res.json(data);
});

Um Request do Express é um IncomingMessage do Node, então entra direto.

Exija uma confirmação recente

app.delete('/keys/:id', requireAuth, async (req, res) => {
  const { error } = await nulvless.auth.sessions.revoke({
    id: req.params.id,
    nonce: req.headers['nlv-sudo-nonce'] as string,
  });

  if (error) return res.status(403).json({ error });
  res.status(204).end();
});

Esse header carrega o código que o usuário digitou depois de o auth.sessions.sudo() tê-lo enviado. Gasto assim, ele autoriza só esta chamada e nunca eleva a sessão. Veja Modo sudo.

Próximos

Nesta página