spring-boot-webflux使用用户名或电子邮件地址登录



我是spring-boot-webflux的新手,正在使用Cassandra作为我的数据库。我不知道如何使用用户名或电子邮件登录。我有三张桌子

用户表

Create Table user (
userid bigint,
username text,
password text,
name text,
email text,
phone text,
birthday text,
biography text,
PRIMARY KEY (userid)
)

user_username表

Create Table user (
username text,
userid bigint,
password text,
name text,
email text,
phone text,
birthday text,
biography text,
PRIMARY KEY (username)
)

用户邮件表

Create Table user (
email text,
username text,
userid bigint,
password text,
name text,
phone text,
birthday text,
biography text,
PRIMARY KEY (email)
)
@PostMapping("/signin")
public Mono<ResponseEntity<?>> login(@RequestBody AuthLoginRequest authLoginRequest) {
return userService.findByUsernameOrEmail(authLoginRequest.getUsernameOrEmail()).map((user) -> {
if(passwordEncoder.encode(authLoginRequest.getPassword()).equals(user.getPassword())) {
return ResponseEntity.ok(new ApiResponse(tokenProvider.generateToken(user)));
}else {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
}.defaultIfEmpty(ResponseEntity.status(HttpStatus.UNAUTHORIZED).build());
}

这就是我将如何返回用户单声道单声道的问题所在。如果他们使用用户名登录,我必须查询userusername表,或者如果他们使用电子邮件地址登录,我也必须查询useremail表。

@Service
public class UserService() {
public Mono<User> findByUsernameOrEmail(String usernameOrEmail) {
}
}

我需要压缩user_username和user_email类吗?请给我一个解决方案,我还没有看到任何相关的问题。求你了,我需要一个有效的解决方案。

根据你的回答@NikolaB,我编辑了这个问题,以展示我迄今为止所做的

public Mono<User> findByUsernameOrEmail(String usernameOrEmail) {
return userUsernameRepository.findById(usernameOrEmail)
.map(userUsername -> {
System.out.println("Checking name "+userUsername.getName());// i printed out the name of the user
return new User(userUsername);
}).switchIfEmpty(userEmailRepository.findById(usernameOrEmail)
.map(userEmail -> {
System.out.println("Checking name " +userEmail.getName());// i printed out the name of the user
return new User(userEmail);
}));
}

一切都很好。。。

我的用户表

public class User {
//My Constructors
public User(UserUsername userUsername) {
System.out.println("Userid " + userUsername.getUserId());/I am getting the userId
User user = new User();
BeanUtils.copyProperties(userUsername, user);
System.out.println("New Userid " + user.getUserId()); //I am getting the userId
}
public User(UserEmail userEmail) {
System.out.println("Userid " + userEmail.getUserId()); /I am getting the userId
User user = new User();
BeanUtils.copyProperties(userEmail, user);
System.out.println("New Userid " + user.getUserId()); /I am getting the userId
}
}

我的后映射

此处用户为空

@PostMapping("/signin")
public Mono<ResponseEntity<?>> login(@RequestBody AuthLoginRequest authLoginRequest) {
return userService.findByUsernameOrEmail(authLoginRequest.getUsernameOrEmail()).map((user) -> {
if(passwordEncoder.encode(authLoginRequest.getPassword()).equals(user.getPassword())) {
return ResponseEntity.ok(new ApiResponse(tokenProvider.generateToken(user)));
}else {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
}.defaultIfEmpty(ResponseEntity.status(HttpStatus.UNAUTHORIZED).build());
}

您需要查询user_username表,如果有条目,则将其映射到User类并返回。如果没有,则需要查询user_email表,如果存在条目则将其映像到UserUsername类。

最简单的方法是使用存储库:

public interface UserUsernameRepository extends ReactiveCassandraRepository<UserUsername, String> {
}

public interface UserEmailRepository extends ReactiveCassandraRepository<UserEmail, String> {
}

以下是用法:

@Service
public class UserService() {
@Autowired
private UserUsernameRepository userUsernameRepository;
@Autowired
private UserEmailRepository userEmailRepository;
public Mono<User> findByUsernameOrEmail(String usernameOrEmail) {
return userUsernameRepository.findById(usernameOrEmail)
.switchIfEmpty(userEmailRepository.findById(usernameOrEmail)
.map(userEmail -> new UserUsername(userEmail))) // or some other way to map properties to UserUsername class
.map(userUsername -> new User(userEmail)) // or some other way to map properties to wanted User class
}
}

若两个查询都没有返回结果(空(,那个么服务方法将返回Mono.empty(),这正是您所需要的。

请注意,必须在new UserUsernamenew UserUsername构造函数中实现属性映射。

编辑

好吧,我想我知道问题出在哪里了,在User构造函数中,您正在创建一个新的User实例,并将UserUsername/UserEmail实例属性映射到该实例化的User实例,而实际上该实例并没有绑定到构造函数返回的实例。在这些构造函数中手动设置字段,如下所示:

public User(UserUsername userUsername) {
System.out.println("Userid " + userUsername.getUserId()); //I am getting the userId
this.email = userUsername.getEmail();
this.username = userUsername.getUsername();
...
}

或者在具有BeanUtils:的服务方法图中

public Mono<User> findByUsernameOrEmail(String usernameOrEmail) {
return userUsernameRepository.findById(usernameOrEmail)
.map(userUsername -> {
System.out.println("Checking name "+userUsername.getName());// i printed out the name of the user
User user = new User();
BeanUtils.copyProperties(userUsername, user);
return user;
}).switchIfEmpty(userEmailRepository.findById(usernameOrEmail)
.map(userEmail -> {
System.out.println("Checking name " +userEmail.getName());// i printed out the name of the user
User user = new User();
BeanUtils.copyProperties(userEmail, user);
return user;
}));
}

最新更新