1
resposta

Implementação de Cadastro na API

Olá a todos, eu estava tendo problemas na autenticação da minha API, a causa era o fato de que as senhas dos meus usuários no banco de dados não estavam criptografadas, por isso decidi implementar a funcionalidade de cadastro para salvar os usuários com senhas já codificadas. Consegui implementar essa funcionalidade e resolvi compartilhar o código aqui no fórum para ajudar quem estiver com dificuldades nessa parte.

Antes de tudo, inseri um registro na entidade Perfil, que representará usuários comuns, com o seguinte comando SQL:

INSERT INTO Perfil (nome) VALUES ('usuario');

É necessário também criar um método na classe usuário para adicionar um Perfil na lista de perfis:

public void adicionaPerfil(Perfil perfil) {
        this.perfis.add(perfil);
    }

Controller responsável por realizar os cadastros:

@RestController
@RequestMapping("/register")
public class CadastroController {

    //Injetando os repositories
    @Autowired
    private UsuarioRepository usuarioRepository;
    @Autowired
    private PerfilRepository perfilRepository;

    @PostMapping
    @Transactional
    public ResponseEntity<?> cadastrar(@RequestBody @Valid CadastroForm form) {

        //Fazendo a validação

        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();
        Set<ConstraintViolation<CadastroForm>> violations = validator.validate(form);

        if (violations.isEmpty()) {
            Usuario usuario = form.toUsuario();

            //Como a chave primária da entidade Usuário é o id, o banco de dados permitirá que
            //existam dois ou mais usuários com o mesmo email, por isso devemos fazer a verificação manualmente.

            if (usuarioRepository.findByEmail(usuario.getEmail()).isPresent()) {
                return ResponseEntity.badRequest().body("Este email já está cadastrado!");
            }

            //Por enquanto, estou definindo todos os usuários que se cadastram como usuários comuns

            usuario.adicionaPerfil(this.perfilRepository.findByNome("usuario"));

            //Codificando a senha, para salvar a senha já criptografada no banco de dados

            String senha = new BCryptPasswordEncoder().encode(usuario.getSenha());
            usuario.setSenha(senha);
            usuarioRepository.save(usuario);

            //O correto seria criar uma URI para detalhar um usuário, mas por enquanto vamos enviar null: 

            return ResponseEntity.created(null).body(new UsuarioDto(usuario.getId(), usuario.getNome(), usuario.getEmail()));
        }

        //Enviando 400 caso haja algum problema de validação

        return ResponseEntity.badRequest().body(violations);
    }

}

Classe PerfilRepository:

public interface PerfilRepository extends JpaRepository<Perfil, Long> {

    Perfil findByNome(String nome);

}

Classe com o formulário de cadastro:

public class CadastroForm {

    //Fazendo algumas validações

    @NotEmpty @NotNull @Email
    private String email;
    @NotEmpty @NotNull @Size(min=3, max=20)
    private String nome;
    @NotEmpty @NotNull @Size(min=6, max=30)
    private String senha;

    // getters, setters e construtores

    }

Classe UsuarioDto, para enviar no ResponseEntity.created():

public class UsuarioDto {

    private Long id;
    private String nome;
    private String email;

    // getters, setters e construtores

    }

Por último, devemos tornar esse endpoint público, no método config da classe SecurityConfigurations:

.antMatchers(HttpMethod.POST, "/register").permitAll()

Isso é tudo, espero ter conseguido ajudar alguém!

1 resposta

Oi Breno,

Muito bom! Ficou bacana a solucao :)

Com certeza vai ajudar quem precisar implementar tal funcionalidade na API.

Bons estudos!