Spring Security + JWT, Angular

Boa noite.

Pessoal, estou desenvolvendo minha primeira aplicação utilizando spring no back, angular no front.
Cheguei na parte que preciso fazer com que cada usuario tenha seus registros e que essa página só possa ser acessada depois de autorização.

Com algumas horas de buscas na internet eu vi que isso se faz com Spring security + jwt, mas não consigo encontrar tutorial nenhum e não consegui entender muito bem as explicações teóricas. O que é isso tudo? Alguém tem algum “algoritmo” pra se seguir e fazer isto funcionar? Algum curso? Alguma coisa?

Muito obrigado pela atenção, estou bem perdido e preciso entender estes conceitos.

ps. Alguns tutoriais que encontrei até explicam como fazer uma autenticação simples, mas é sempre hard-coded usuario e senha. No meu banco eu moldei tabela usuário para poder ter um cadastro, nome, senha, id, etc. Um usuário tem várias notas, tudo relacionado certinho.

esse video foi o que eu achei mais clean, de implementar. e é facil de entender. Porem esta em ingles.

spring security + jwt

eu tenho isso funcionando, porem, se voce ver as classes sem entender… vai ser confuso pq de fato é confuso.

1 curtida

Obrigado pela resposta amigo!
Então, este é um dos vídeos que tentei acompanhar e adaptar ao meu projeto… Só que neste vídeo ele define um usuário e senha hardcoded, e eu precisava fazer inserção e autenticação por usuários do banco.
Encontrei alguns códigos na internet e consigo passar um usuário e senha que me gera um token, mas realmente não entendi o funcionamento hahaha

Olá Idzsmaga,

Existe um curso na udemy que aborda Spring Security+JWT+Angular e como implementa-lós, se não estiver com muita pressa pode fazer esse investimento, eu garanto que vai sair com um conhecimento sólido do assunto. Você pode acessar o link abaixo.

Caso já tenha um conhecimento teórico e queira ir direto para a implementação. Pode olhar esses dois repositórios do GitHub. Na descrição do commit tem tudo que foi implementado, tanto no repositorio da API, que mostra como gerar o token, criar perfil e etc. Até o consumo de uma API com angular capturando um token e usando autorização.

Link Código API Spring

Link Aplicação Angular:

Olhando esses códigos pode extrair algo que ajude, mas recomendo o curso porque acrescenta muito.

Abraço e bons estudos!!

1 curtida

Amigo, obrigado pela resposta!
Estou com o curso de Java do Nelio em andamento, tive que dar uma pausa para terminar este projeto com spring/angular, para a faculdade.

O projeto em si é para 12/06, creio que pegando o curso hoje eu consigo adaptar às minhas necessidades antes deste prazo.
Não sabia que ele tinha este curso, realmente, ele é um ótimo instrutor. Obrigado pelas dicas, e se o tempo apertar, dou uma olhada no github sim. Obrigado!

eu sinceramente nao gostei da abordagem do jwt usando spring security, ele nao tem suporte nativo, e isso é uma adaptacao. usando node.js e a lib jsonwebtoken, o codigo para gerar e verificar a validade do token se resumem a pouquissimas linhas. porem no java. com spring-security é essa novela. Eu tenho o exemplo de codigo que devensolvi baseado nisso que voce viu. No inicio achei confuso. mas no final entendi o fluxo. a unica coisa que nao gostei, é que voce precisa colocar um filtro de captura que pega todas as requisicoes e verifica o token, e para cada requisicao a api, para validar o token ele faz select no banco. achei isso desnecessario.

Vc não depende mais de lib externa além do Spring Security, veja estas postagens:

E aqui uma abordagem implementando o fluxo com PKCE do OAuth2:

eu ja li o segundo arquivo que voce passou. inclusive li todo essa manual do proprio spring. o oauth2 + jwt. mas mesmo assim… eh confuso, pq precisa de varias classes. para fazer ao meu ver uma coisa bem simples.

Pior que é confuso mesmo. Eu tive que quebrar bastante a cabeça pra entender.

Olha a diferenca usando nodejs.

const Usuario = require('../models/usuario');
const jwt = require('jsonwebtoken');

const assertCredentials = async (username, password) => {
  const usuario = await Usuario.findOne({
      where: { login: username }
  })

  if (usuario && (usuario.senha === password)) {
    usuario.senha = undefined;
    return usuario
  }
  return Promise.reject(new Error('Dados de usuário inválidos'))
}

const autenticar = async (req, res, next) => {
  try {
    const { username, password } = req.body;

    const user = await assertCredentials(username, password);

    const token = await jwt.sign({ id: user.id }, process.env.SECRET, { expiresIn: '6h', });

    res.json({ token, user });
  } catch (err) {
    next(err)
  }
}
module.exports = {
    autenticar
};

e aqui é um middleware que para cada requisicicao valida o token.

const jwt = require('jsonwebtoken');

module.exports = (req, res, next) => {
    const authorization = req.headers.authorization;
    if (!authorization) {
        return res.status(401).json({ message: 'Nenhum token fornecido.' })
    }
    const parts = authorization.split(' ');
    if (!parts.length === 2) {
        return res.status(401).json({ message: 'Formato padrão do token inválido' })
    }
    const [schema, token] = parts;
    if (!/^Bearer$/i.test(schema)) {
        return res.status(401).json({ message: 'Formato do token inválido' })
    }
    jwt.verify(token, process.env.SECRET, (err, decoded) => {
        if (err) {
            return res.status(401).json({ message: 'Token inválido' })
        }
        req.usuarioId = decoded.id;
        return next();
    })
}

bem simples e nada confuso.

1 curtida