Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

[Dúvida] Transforma senha em hash

Gostaria de saber como ficaria a parte do controller caso eu quisesse criar uma rota do tipo POST para cadastrar um usuário, com o detalhe de que, em vez de salvar a senha no seu formato original, ela seria convertida em um hash (bcrypt) e, em seguida, salva no banco de dados.

No exemplo abaixo está o código que tenho. O que deveria ser adicionado ou removido para tornar isso possível?

controller user

  @PostMapping("/crateNewUserr")
    @Transactional
    public ResponseEntity cadastrarUsuario(@RequestBody @Valid DataUserCreate dados, UriComponentsBuilder uriBuilder) {
        var user = new User(dados);
        repository.save(user);

        var uri = uriBuilder.path("/user/{id}").buildAndExpand(user.getId()).toUri();

        return ResponseEntity.created(uri).body(new DtoCustomerReturn(user));
    }

Entity

@Table(name = "users")
@Entity(name = "Users")
@Getter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = "id")
public class User implements UserDetails {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String login;
    private String password;

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return List.of(new SimpleGrantedAuthority("ROLE_USER"));
    }
    @Override
    public String getPassword() {
        return password;
    }
    @Override
    public String getUsername() {
        return login;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}
DTO
package projeto.crud.joao.com.apicrud.domain.user;

public record DtoUserData(
        String login,
        String password
) {
}
1 resposta
solução!

Para integrar a geração de hash de senha com bcrypt no seu controller de cadastro de usuários, você precisa fazer algumas alterações e adições ao seu código. O principal objetivo é garantir que a senha fornecida pelo usuário seja hasheda antes de ser salva no banco de dados. Para isso, você pode usar o BCryptPasswordEncoder do Spring Security.

Aqui está como você poderia modificar o seu controller para incluir essa funcionalidade:

  1. Adicionar a Dependência do BCrypt: Primeiramente, certifique-se de que você tem a dependência do Spring Security no seu arquivo pom.xml ou build.gradle, pois é ela que fornece o BCryptPasswordEncoder.

    Maven (pom.xml):

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    

    Gradle (build.gradle):

    implementation 'org.springframework.boot:spring-boot-starter-security'
    
  2. Modificar o Controller para Hashedar a Senha:

    Você pode modificar o método que lida com a criação do usuário para hashedar a senha antes de salvá-la no banco de dados. Isso pode ser feito instanciando BCryptPasswordEncoder e usando-o para gerar o hash da senha.

    Aqui está um exemplo modificado do seu controller:

    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    // Outras importações...
    
    @RestController
    public class UserController {
    
        @Autowired
        private UserRepository repository;
    
        @PostMapping("/createNewUser")
        @Transactional
        public ResponseEntity cadastrarUsuario(@RequestBody @Valid DataUserCreate dados, UriComponentsBuilder uriBuilder) {
            var encoder = new BCryptPasswordEncoder();
            var hashedPassword = encoder.encode(dados.getPassword());
            
            var user = new User(dados.getLogin(), hashedPassword); // Supondo que você tenha um construtor adequado
            repository.save(user);
    
            var uri = uriBuilder.path("/user/{id}").buildAndExpand(user.getId()).toUri();
    
            return ResponseEntity.created(uri).body(new DtoCustomerReturn(user));
        }
    }
    

    Nota: O ideal é não instanciar BCryptPasswordEncoder diretamente no método devido a questões de performance e gerenciamento de beans do Spring. Uma prática melhor é declará-lo como um bean no seu contexto do Spring e injetá-lo onde necessário.

  3. Definir BCryptPasswordEncoder como um Bean:

    No seu arquivo de configuração do Spring ou na classe principal da aplicação, você pode definir um bean para o BCryptPasswordEncoder:

    import org.springframework.context.annotation.Bean;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class SecurityConfig {
        @Bean
        public BCryptPasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    }
    

    E então modificar o controller para injetar o BCryptPasswordEncoder:

    @Autowired
    private BCryptPasswordEncoder encoder;
    

    E usar esse encoder injetado para hashedar a senha.

Essas modificações garantirão que a senha do usuário seja armazenada de forma segura no banco de dados, usando hash bcrypt, o que é uma prática recomendada para a segurança das credenciais de usuário.

Insira aqui a descrição dessa imagem para ajudar na acessibilidade