Autenticação no next js

Este projeto implementa um fluxo completo de autenticação usando JWT para autenticar usuários com email e senha. Utiliza o conceito de fila para atualizar o token e SSR do Next.js para atualizar o token no servidor e validar as permissões do usuário.

Front End
ReactJs
NextJs
TypeScript

Carregando ...

Sobre

Este projeto implementa um fluxo completo de autenticação usando JWT (JSON Web Tokens) para autenticar usuários com email e senha. Ele atualiza o token do usuário sempre que ele expira, utilizando o conceito de fila. Além disso, utiliza o SSR (Server Side Rendering) do Next.js para atualizar o token no servidor e validar as permissões do usuário para acessar rotas específicas ou componentes. O projeto utiliza uma API localizada na pasta api, que contém algumas rotas para implementar a autenticação no front-end.

Fluxo de autenticação

O fluxo de autenticação funciona da seguinte maneira:

  1. Login: O usuário insere seu email e senha. O aplicativo faz uma chamada para a API com esses dados, salva o token e o refresh token nos cookies do navegador, salva os dados do usuário em um estado no contexto de autenticação e atualiza o header de Authorization com o valor do token.

  2. Refresh Token: Quando o token do usuário expira, o aplicativo intercepta a resposta do servidor, verifica se o erro é devido a um token expirado e, se for, faz uma requisição para a rota /refresh para obter um novo token. As requisições que falharam devido ao token expirado são colocadas em uma fila e refeitas após o token ser atualizado.

if (error.response?.status === 401) {
const data = error.response.data as ExtendsErrorData
 
if (data.code === 'token.expired') {
  cookies = parseCookies(ctx)
 
  const { 'nextAuth.refreshToken': refreshToken } = cookies
 
  const originalConfig = error.config
 
  if (!isRefreshing) {
    isRefreshing = true
 
    api
      .post('/refresh', {
        refreshToken,
      })
      .then((response) => {
        const { token } = response.data
 
        setCookie(ctx, 'nextAuth.token', token, {
          maxAge: 60 * 60 * 24 * 30,
          path: '/',
        })
 
        setCookie(
          ctx,
          'nextAuth.refreshToken',
          response.data.refreshToken,
          {
            maxAge: 60 * 60 * 24 * 30,
            path: '/',
          },
        )
 
        api.defaults.headers.Authorization = `Bearer ${token}`
 
        failedRequestQueue.forEach((request) =>
          request.onSuccess(token),
        )
        failedRequestQueue = []
      })
      .catch((err) => {
        failedRequestQueue.forEach((request) => request.onFailure(err))
        failedRequestQueue = []
 
        if (process.browser) {
          signOut()
        }
      })
      .finally(() => {
        isRefreshing = false
      })
  }
 
  return new Promise((resolve, reject) => {
    failedRequestQueue.push({
      onSuccess: (token: string) => {
        if (originalConfig) {
          originalConfig.headers.Authorization = `Bearer ${token}`
 
          resolve(api(originalConfig))
        }
      },
      onFailure: (error: AxiosError) => {
        reject(error)
      },
    })
  })
} else {
  if (process.browser) {
    signOut()
  } else {
    return Promise.reject(new AuthTokenError())
  }
}
}

Instalação

Siga estas etapas para instalar e configurar o projeto em seu ambiente local.

Clone o repositório

Clone o repositório do projeto em seu ambiente local e acesse a pasta do projeto.

git clone git clone git@github.com:manoguii/auth-next-js.git
cd auth-next-js

Instale as dependências e execute a aplicação

Instale as dependências do projeto e execute a aplicação em modo de desenvolvimento.

pnpm install
pnpm dev

O projeto estará disponível em seu navegador em http://localhost:3000.

Usuários para teste

Para testar a aplicação você pode usar os seguintes usuários.

{
  email: 'guilhermedavidrk@gmail.com',
  password: '123456',
  permissions: ['users.list', 'users.create', 'metrics.list'],
  roles: ['administrator']
},
{
  email: 'estagiario@gmail.com',
  password: '123456',
  permissions: ['products.list'],
  roles: ['editor']
},

Tecnologias

Algumas tecnologias utilizadas para construção da aplicação.