【问题标题】:Saving into database returns all the user data including encoded password保存到数据库返回所有用户数据,包括编码密码
【发布时间】:2021-08-22 11:22:08
【问题描述】:

我正在尝试根据来自 Amigoscode Youtube: Java Tutorial 的教程构建用户注册, Git Repository,但我让它与 webflux、postgresql 和 R2DBC 反应。

现在我正在努力将用户数据保存到数据库中。如果我像教程中那样做,注册方法的返回类型是字符串,它根本不会保存数据。所以我将返回类型更改为ApplicationUser并将save()放入返回中,但是现在,如果我用邮递员调用端点,它将保存数据,但它也会将所有用户数据包括加密密码返回给邮递员.我不确定这是多大的问题,但我宁愿避免这种行为。怎么办?

这是保存到数据库但返回所有数据的版本:
ApplicationUserService.java

@RequiredArgsConstructor
@Service
public class ApplicationUserService implements ReactiveUserDetailsService {

    private final static String USER_NOT_FOUND_MSG = "User with email %s not found";

    private final UserRepository userRepository;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;

    public Mono<ApplicationUser> signUpUser(ApplicationUser applicationUser){

        String encodedPassword = bCryptPasswordEncoder.encode(applicationUser.getPassword());

        applicationUser.setPassword(encodedPassword);

        return userRepository.findByEmail(applicationUser.getEmail())
                // .flatMap(t -> { throw new IllegalStateException("Email already exists"); })
                .switchIfEmpty(userRepository.save(applicationUser));             
    }


这个版本不返回数据,也不保存到数据库:
需要在其他函数中将返回类型从 Mono&lt;ApplicationUser&gt; 更改为 Mono&lt;String&gt;
ApplicationUserService.java

@RequiredArgsConstructor
@Service
public class ApplicationUserService implements ReactiveUserDetailsService {

    private final static String USER_NOT_FOUND_MSG = "User with email %s not found";

    private final UserRepository userRepository;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;

    public Mono<String> signUpUser(ApplicationUser applicationUser){

        String encodedPassword = bCryptPasswordEncoder.encode(applicationUser.getPassword());

        applicationUser.setPassword(encodedPassword);

        userRepository.findByEmail(applicationUser.getEmail())
                .flatMap(t -> { throw new IllegalStateException("Email already exists"); })
                .switchIfEmpty(userRepository.save(applicationUser)); 

        return Mono.just("Sign up works, maybe");           
    }

这会返回“注册工作,也许”,就是这样。未保存任何数据。

剩余功能

ApplicationUser.java

@Data
@NoArgsConstructor
@Table("users")
public class ApplicationUser implements UserDetails { 
 
    @Id
    private long id;
    private String username;  
    private String password;
    private String email;
    private UserRole userRole;
    private boolean isAccountNonExpired = true;
    private boolean locked = false;
    private boolean isCredentialsNonExpired = true;
    private boolean isEnabled = false;

    public ApplicationUser(String username, String password, String email,UserRole userRole) {
                               this.username = username;
                               this.password = password;
                               this.email = email;
                               this.userRole = userRole;
                           }
      
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        SimpleGrantedAuthority authority = new SimpleGrantedAuthority(userRole.name());
        return Collections.singletonList(authority);
    }

    @Override
    public String getPassword() {
        // TODO Auto-generated method stub
        return password;
    }

    @Override
    public String getUsername() {
        // TODO Auto-generated method stub
        return username;
    }

    @Override
    public boolean isAccountNonExpired() {
        // TODO Auto-generated method stub
        return isAccountNonExpired;
    }

    @Override
    public boolean isAccountNonLocked() {
        // TODO Auto-generated method stub
        return locked;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        // TODO Auto-generated method stub
        return isCredentialsNonExpired;
    }

    @Override
    public boolean isEnabled() {
        // TODO Auto-generated method stub
        return isEnabled;
    }

    
}

UserRole.java

public enum UserRole {

    USER,
    ADMIN,
    MODERATOR
}

UserRepository.java

@Repository
@Transactional(readOnly = true)
public interface UserRepository extends ReactiveCrudRepository<ApplicationUser, Long>{

    Mono<ApplicationUser> findByEmail(String email);
    
}

RegistrationController.java

@RestController
@RequestMapping(path = "/registration")
@AllArgsConstructor
public class RegistrationController {

    private RegistrationService registrationService;

    @PostMapping
    public Mono<ApplicationUser> register(@RequestBody RegistrationRequest request){ 
        return registrationService.reg(request);
    }
    
}

RegistrationService.java

@Data
@Service
@AllArgsConstructor
public class RegistrationService {

    private EmailValidator emailValidator;
    private ApplicationUserService applicationUserService;
  
    public Mono<ApplicationUser> reg(RegistrationRequest request) { 

        Boolean isValidEmail = emailValidator.test(request.getEmail());

        if(!isValidEmail) {
            throw new IllegalStateException("Email not valid");
        }

        return applicationUserService.signUpUser(
            new ApplicationUser(
                request.getUsername(),
                request.getPassword(),
                request.getEmail(),              
                UserRole.USER

             )
        );
    }
    
}

RegistrationRequest.java

@Data
@AllArgsConstructor
@ToString
public class RegistrationRequest {

    private String username;
    private String password;
    private String email;
    private UserRole userRole;   
}

【问题讨论】:

    标签: java spring postgresql spring-webflux spring-data-r2dbc


    【解决方案1】:

    如果您想在保存到数据库后返回 String,您只需确保不会破坏响应链:

    public Mono<String> signUpUser(ApplicationUser applicationUser){
        String encodedPassword = bCryptPasswordEncoder.encode(applicationUser.getPassword());
    
        applicationUser.setPassword(encodedPassword);
    
        return userRepository.findByEmail(applicationUser.getEmail())
                .flatMap(t -> { throw new IllegalStateException("Email already exists"); })
                .switchIfEmpty(userRepository.save(applicationUser))
                .thenReturn("Sign up works, for sure");        
    }
    

    否则,如果您破坏了链条,那么“在您订阅之前什么都不会发生”的规则会咬住您。这就是为什么您只看到返回的 String 而没有看到用户保存的原因。由于没有订阅保存操作,因此没有执行。

    【讨论】:

    • 好的,是的。那也有效。万分感谢。但不是这样先发送用户数据然后发送字符串吗?我无法观察到这一点,但只是为了确定。
    • 是一个单值的Mono,所以最后只返回String。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-12
    • 2016-04-22
    • 1970-01-01
    • 2017-01-05
    • 1970-01-01
    • 2017-07-21
    相关资源
    最近更新 更多