Trabalhando com autenticação e autorização em Node.js: JWT e Passport.js
Tags: node, javascript, jwt, programming
Published: 2023-05-13 19:03:44

A autenticação e autorização são recursos fundamentais para a segurança em aplicações web, permitindo controlar o acesso de usuários a determinadas áreas e recursos do sistema. 

No Node.js, existem diversas ferramentas disponíveis para implementar esses recursos, como o JWT (JSON Web Tokens) e o Passport.js. 

Neste artigo, vamos falar sobre como trabalhar com essas ferramentas em conjunto, garantindo a segurança e a confiabilidade das aplicações.

### Configurando o ambiente
Antes de começar a trabalhar com JWT e Passport.js, precisamos configurar nosso ambiente de desenvolvimento. Certifique-se de que o Node.js e o NPM estão instalados em sua máquina. 

Em seguida, crie um novo diretório e inicialize um novo projeto Node.js executando o seguinte comando:

```csharp
npm init -y
```

Em seguida, instale as seguintes dependências usando o comando:

```csharp
npm install express jsonwebtoken passport passport-jwt cors
```

## JSON Web Tokens (JWT)

O JWT é um padrão aberto para criação de tokens de acesso, que podem ser usados para autenticação e autorização em aplicações web. 

Esses tokens são criptografados e contêm informações sobre o usuário, como nome, email, permissões, entre outras. Ao contrário de sessões tradicionais, que são armazenadas no servidor, os tokens JWT são armazenados no lado do cliente, o que traz diversas vantagens em termos de escalabilidade, performance e segurança.

Para gerar um token JWT, é necessário passar um objeto com as informações do usuário e uma chave secreta para o método jwt.sign(). 

Exemplo:

```js
const jwt = require('jsonwebtoken');

const user = {
  id: 1,
  name: 'John Doe',
  email: 'johndoe@example.com',
  permissions: ['admin']
};

const token = jwt.sign(user, 'secret-key');

```

O token gerado será uma string criptografada que pode ser enviada para o cliente, geralmente como um cookie ou um header HTTP.

Para validar um token JWT, basta usar o método jwt.verify() passando o token e a chave secreta:

```ts
const decoded = jwt.verify(token, 'secret-key');

```

O método retorna um objeto com as informações do usuário contidas no token, caso o token seja válido. Caso contrário, será lançada uma exceção.

## Passport.js

O Passport.js é um middleware de autenticação para Node.js que permite autenticar usuários usando diferentes estratégias, como JWT, OAuth, Basic Auth, entre outras. O Passport.js também é capaz de lidar com autorização, verificando as permissões de cada usuário.

Para usar o Passport.js em uma aplicação Node.js, é necessário instalar os pacotes passport e passport-jwt:

```bash
npm install passport passport-jwt

```

Em seguida, é necessário configurar uma estratégia de autenticação, definindo como o Passport.js vai verificar os tokens JWT. 

Exemplo:

```js
const passport = require('passport');
const JwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;

const options = {
  jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
  secretOrKey: 'secret-key'
};

passport.use(new JwtStrategy(options, (payload, done) => {
  User.findById(payload.sub)
    .then(user => {
      if (user) {
        return done(null, user);
      } else {
        return done(null, false);
      }
    })
    .catch(err => done(err, false));
}));

```

Nesse exemplo, a estratégia de autenticação usa o método ExtractJwt.fromAuthHeaderAsBearerToken() para extrair o token JWT.


## Criando rotas de autenticação

Para criar rotas de autenticação em Node.js com JWT e Passport.js, é necessário seguir alguns passos:

1- Configure o Passport.js para usar o JWT(como já foi mostrado acima):

```js
const passport = require('passport');
const JwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;

const options = {
  jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
  secretOrKey: 'your_jwt_secret'
};

passport.use(new JwtStrategy(options, (payload, done) => {
  // Find the user in the database and return it
  // Call done() with an error if the user doesn't exist
  done(null, user);
}));

```

Nesse exemplo, estamos configurando o Passport.js para extrair o JWT do cabeçalho de autenticação Bearer e usar uma chave secreta para verificar a assinatura do token. 

Também estamos definindo uma estratégia de autenticação baseada em JWT.

2- Crie uma rota para autenticação:

```js
const jwt = require('jsonwebtoken');

router.post('/login', (req, res) => {
  // Authenticate the user
  const user = { id: 1, name: 'John Doe' };

  // Generate a JWT
  const token = jwt.sign(user, 'your_jwt_secret');

  // Return the token to the client
  res.json({ token });
});

```

Nesse exemplo, estamos autenticando o usuário e gerando um token JWT com o método jwt.sign(). Em seguida, estamos retornando o token para o cliente em formato JSON.

3- Proteja as rotas que precisam de autenticação:

```js
const passport = require('passport');

router.get('/protected', passport.authenticate('jwt', { session: false }), (req, res) => {
  res.json({ message: 'This is a protected route' });
});

```

Nesse exemplo, estamos usando o middleware passport.authenticate() para proteger a rota /protected. 

Esse middleware verifica se o token JWT é válido e, se for, adiciona o objeto user ao objeto req.


Com esses passos, você pode criar rotas de autenticação em Node.js com JWT e Passport.js. 

É importante lembrar de proteger as rotas que precisam de autenticação e de armazenar a chave secreta de forma segura.


Referencias:

[jwt](https://jwt.io/)
[Passport](https://www.passportjs.org/)
[https://www.digitalocean.com/community/tutorials/api-authentication-with-json-web-tokensjwt-and-passport](https://www.digitalocean.com/community/tutorials/api-authentication-with-json-web-tokensjwt-and-passport)