在现代应用程序中,短信验证成为了一种常见的用户登录和注册方式,因为它安全可靠,且用户体验良好。在这篇文章中,我们将使用SpringBoot实现短信验证登录和注册的逻辑。我们将从创建交互对象开始,逐步实现业务逻辑,并最终测试我们的接口。
1. 创建交互对象
首先,我们需要创建交互对象来处理用户输入和输出。我们将创建以下对象:
用户短信登录/注册 DTO (Data Transfer Object)
public class UserSmsLoginDto {
private String phoneNumber;
private String verificationCode;
// getters and setters
}
用户登录 VO (View Object)
public class UserLoginVo {
private String token;
// getters and setters
}
2. 创建自定义业务异常
为了更好地处理业务逻辑中可能出现的异常情况,我们创建自定义业务异常。
验证码错误异常
public class VerificationCodeException extends RuntimeException {
public VerificationCodeException(String message) {
super(message);
}
}
用户被封禁异常
public class UserBannedException extends RuntimeException {
public UserBannedException(String message) {
super(message);
}
}
用户注册失败异常
public class UserRegistrationFailedException extends RuntimeException {
public UserRegistrationFailedException(String message) {
super(message);
}
}
3. 登录注册业务逻辑实现
现在,我们可以实现登录和注册的业务逻辑了。
登录业务逻辑
@Service
public class AuthService {
@Autowired
private UserService userService;
@Autowired
private SmsService smsService;
@Autowired
private JwtTokenProvider jwtTokenProvider;
public UserLoginVo loginUser(UserSmsLoginDto userDto) {
String phoneNumber = userDto.getPhoneNumber();
String verificationCode = userDto.getVerificationCode();
if (!smsService.verifyCode(phoneNumber, verificationCode)) {
throw new VerificationCodeException("Invalid verification code.");
}
User user = userService.findByPhoneNumber(phoneNumber);
if (user == null || user.isBanned()) {
throw new UserBannedException("User is banned or does not exist.");
}
String token = jwtTokenProvider.createToken(phoneNumber);
return new UserLoginVo(token);
}
}
注册业务逻辑
@Service
public class AuthService {
@Autowired
private UserService userService;
@Autowired
private SmsService smsService;
public void registerUser(UserSmsLoginDto userDto) {
String phoneNumber = userDto.getPhoneNumber();
String verificationCode = userDto.getVerificationCode();
if (!smsService.verifyCode(phoneNumber, verificationCode)) {
throw new VerificationCodeException("Invalid verification code.");
}
User user = new User();
user.setPhoneNumber(phoneNumber);
if (!userService.saveUser(user)) {
throw new UserRegistrationFailedException("Failed to register user.");
}
}
}
4. 测试接口
现在,我们可以编写测试用例来测试我们的登录和注册接口。
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class AuthControllerTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
public void testLogin() {
UserSmsLoginDto userDto = new UserSmsLoginDto();
userDto.setPhoneNumber("1234567890");
userDto.setVerificationCode("123456");
ResponseEntity<UserLoginVo> responseEntity = restTemplate.postForEntity("/login", userDto, UserLoginVo.class);
assertEquals(HttpStatus.OK, responseEntity.getStatusCode());
assertNotNull(responseEntity.getBody().getToken());
}
@Test
public void testRegister() {
UserSmsLoginDto userDto = new UserSmsLoginDto();
userDto.setPhoneNumber("1234567890");
userDto.setVerificationCode("123456");
ResponseEntity<Void> responseEntity = restTemplate.postForEntity("/register", userDto, Void.class);
assertEquals(HttpStatus.OK, responseEntity.getStatusCode());
}
}