feat(auth): bind code to the requesting user
Store the username and email alongside the code in the cached EmailVerificationCode object, and reject registration when the username or email no longer match the original request.
This commit is contained in:
2 files changed
+29
-5
No files matched your search
@@ -0,0 +1,8 @@
|
|||||||
|
package com.onixbyte.deltaforceguide.domain.dto;
|
||||||
|
|
||||||
|
public record EmailVerificationCode(
|
||||||
|
String username,
|
||||||
|
String email,
|
||||||
|
String code
|
||||||
|
) {
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package com.onixbyte.deltaforceguide.service;
|
|||||||
import com.onixbyte.captcha.text.TextProducer;
|
import com.onixbyte.captcha.text.TextProducer;
|
||||||
import com.onixbyte.deltaforceguide.client.EmailClient;
|
import com.onixbyte.deltaforceguide.client.EmailClient;
|
||||||
import com.onixbyte.deltaforceguide.client.TokenClient;
|
import com.onixbyte.deltaforceguide.client.TokenClient;
|
||||||
|
import com.onixbyte.deltaforceguide.domain.dto.EmailVerificationCode;
|
||||||
import com.onixbyte.deltaforceguide.domain.dto.LoginRequest;
|
import com.onixbyte.deltaforceguide.domain.dto.LoginRequest;
|
||||||
import com.onixbyte.deltaforceguide.domain.dto.RegisterRequest;
|
import com.onixbyte.deltaforceguide.domain.dto.RegisterRequest;
|
||||||
import com.onixbyte.deltaforceguide.domain.dto.SendVerificationCodeRequest;
|
import com.onixbyte.deltaforceguide.domain.dto.SendVerificationCodeRequest;
|
||||||
@@ -118,13 +119,24 @@ public class AuthService {
|
|||||||
var code = request.verificationCode();
|
var code = request.verificationCode();
|
||||||
var verificationCodeId = request.verificationCodeId();
|
var verificationCodeId = request.verificationCodeId();
|
||||||
|
|
||||||
var storedCode = redisTemplate.opsForValue().get("verification-code:" + verificationCodeId);
|
var _req = redisTemplate.opsForValue().get("verification-code:" + verificationCodeId);
|
||||||
if (!(storedCode instanceof String strStoredCode)) {
|
if (!(_req instanceof EmailVerificationCode verificationCode)) {
|
||||||
log.error("storedCode not a String, storedCode={}", storedCode);
|
log.error("_req not a EmailVerificationCode, storedCode={}", _req);
|
||||||
throw new InternalServerErrorException("系统内部错误,请重试");
|
throw new InternalServerErrorException("系统内部错误,请重试");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!code.equalsIgnoreCase(strStoredCode)) {
|
if (!request.username().equals(verificationCode.username())
|
||||||
|
|| !request.email().equals(verificationCode.email())) {
|
||||||
|
log.error(
|
||||||
|
"Username and email address do not match the data submitted "
|
||||||
|
+ "when requesting the verification code."
|
||||||
|
);
|
||||||
|
log.error("EmailVerificationCode={}", verificationCode);
|
||||||
|
log.error("RegisterRequest={}", request);
|
||||||
|
throw new BadRequestException("用户名或邮箱与获取验证码时不一致,请重新获取验证码。");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!code.equalsIgnoreCase(verificationCode.code())) {
|
||||||
throw new BadRequestException("邮箱验证码不正确,请重试。");
|
throw new BadRequestException("邮箱验证码不正确,请重试。");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,7 +201,11 @@ public class AuthService {
|
|||||||
var code = textProducer.getText();
|
var code = textProducer.getText();
|
||||||
|
|
||||||
// Save verification code to cache.
|
// Save verification code to cache.
|
||||||
redisTemplate.opsForValue().set("verification-code:" + uuid, code, Duration.ofMinutes(10L));
|
redisTemplate.opsForValue().set(
|
||||||
|
"verification-code:" + uuid,
|
||||||
|
new EmailVerificationCode(request.username(), request.email(), code),
|
||||||
|
Duration.ofMinutes(10L)
|
||||||
|
);
|
||||||
|
|
||||||
// Send email.
|
// Send email.
|
||||||
emailClient.sendVerificationCode(request.email(), request.username(), code, 10);
|
emailClient.sendVerificationCode(request.email(), request.username(), code, 10);
|
||||||
|
|||||||
Reference in new issue
Block a user