注册图形验证码实现,用户名注册可成功

main
哆哆咯哆哆咯 7 days ago
parent 46dbe3cd1d
commit 46ce1ba39f

@ -16,6 +16,8 @@ public class WebMvcConfig implements WebMvcConfigurer {
registry.addInterceptor(authInterceptor) registry.addInterceptor(authInterceptor)
.excludePathPatterns("/user/login", .excludePathPatterns("/user/login",
"/user/register", "/user/register",
"/user/captcha",
"/user/verify-captcha",
"/post/list", "/post/list",
"/post/detail", "/post/detail",
"/comment/list", "/comment/list",

@ -10,4 +10,4 @@ public class LuojiaChannelApplication {
SpringApplication.run(LuojiaChannelApplication.class, args); SpringApplication.run(LuojiaChannelApplication.class, args);
} }
} }

@ -0,0 +1,84 @@
package com.luojia_channel.modules.captcha.controller;
import com.luojia_channel.common.domain.Result;
import com.luojia_channel.modules.captcha.utils.CaptchaUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@RestController
@RequestMapping("/user")
@Tag(name = "图形验证码", description = "图形验证码相关接口")
public class CaptchaController {
@Autowired
private RedisTemplate<String, String> redisTemplate;
/**
*
* @param request
* @param res
* @throws IOException
*/
@GetMapping("/captcha")
@Operation(
summary = "生成验证码图片"
)
public void generateCaptcha(HttpServletRequest request,
HttpServletResponse res) throws IOException {
CaptchaUtils captcha = new CaptchaUtils();
BufferedImage image = captcha.getImage();
String text = captcha.getText();
String captchaKey = UUID.randomUUID().toString();
redisTemplate.opsForValue().set("captcha:" + captchaKey, text, 60, TimeUnit.SECONDS);
Cookie cookie = new Cookie("captchaKey", captchaKey);
cookie.setPath("/");
res.addCookie(cookie);
CaptchaUtils.output(image,res.getOutputStream());
}
/**
*
* @param session
* @param params
* @return
*/
@PostMapping("/verify-captcha")
public Result verifyCaptcha(@RequestBody Map<String, String> params, @CookieValue(value = "captchaKey", required = false) String captchaKey, HttpSession session) {
String captcha = params.get("captcha");
if (captchaKey == null) {
return Result.fail(500, "验证码已失效,请重新获取");
}
String redisKey = "captcha:" + captchaKey;
String correctCaptcha = redisTemplate.opsForValue().get(redisKey);
if (correctCaptcha == null) {
return Result.fail(500, "验证码已过期,请重新获取");
}
if (captcha.equalsIgnoreCase(correctCaptcha)) {
redisTemplate.delete(redisKey);
return Result.success();
} else {
return Result.fail(500, "图形验证码错误");
}
}
}

@ -0,0 +1,135 @@
package com.luojia_channel.modules.captcha.utils;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
public class CaptchaUtils {
/**
*
*/
private int width = 180;
/**
*
*/
private int height = 30;
/**
*
*/
private String[] fontNames = { "宋体", "楷体", "隶书", "微软雅黑" };
/**
*
*/
private Color bgColor = new Color(255, 255, 255);
/**
*
*/
private Random random = new Random();
/**
* code
*/
private String codes = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
/**
*
*/
private String text;
/**
*
* @return
*/
private Color randomColor() {
int red = random.nextInt(150);
int green = random.nextInt(150);
int blue = random.nextInt(150);
return new Color(red, green, blue);
}
/**
*
*
* @return
*/
private Font randomFont() {
String name = fontNames[random.nextInt(fontNames.length)];
int style = random.nextInt(4);
int size = random.nextInt(5) + 24;
return new Font(name, style, size);
}
/**
*
*
* @return
*/
private char randomChar() {
return codes.charAt(random.nextInt(codes.length()));
}
/**
* BufferedImage
*
* @return
*/
private BufferedImage createImage() {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = (Graphics2D) image.getGraphics();
//设置验证码图片的背景颜色
g2.setColor(bgColor);
g2.fillRect(0, 0, width, height);
return image;
}
public BufferedImage getImage() {
BufferedImage image = createImage();
Graphics2D g2 = (Graphics2D) image.getGraphics();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 4; i++) {
String s = randomChar() + "";
sb.append(s);
g2.setColor(randomColor());
g2.setFont(randomFont());
float x = i * width * 1.0f / 4;
g2.drawString(s, x, height - 8);
}
this.text = sb.toString();
drawLine(image);
return image;
}
/**
* 线
*
* @param image
*/
private void drawLine(BufferedImage image) {
Graphics2D g2 = (Graphics2D) image.getGraphics();
int num = 5;
for (int i = 0; i < num; i++) {
int x1 = random.nextInt(width);
int y1 = random.nextInt(height);
int x2 = random.nextInt(width);
int y2 = random.nextInt(height);
g2.setColor(randomColor());
g2.setStroke(new BasicStroke(1.5f));
g2.drawLine(x1, y1, x2, y2);
}
}
public String getText() {
return text;
}
public static void output(BufferedImage image, OutputStream out) throws IOException {
ImageIO.write(image, "PNG", out);
}
}

@ -21,7 +21,7 @@ public class ValidateUserUtil {
private final UserMapper userMapper; private final UserMapper userMapper;
/** /**
* *
* *
* @param userRegisterDTO * @param userRegisterDTO
*/ */
@ -30,10 +30,6 @@ public class ValidateUserUtil {
String password = userRegisterDTO.getPassword(); String password = userRegisterDTO.getPassword();
String phone = userRegisterDTO.getPhone(); String phone = userRegisterDTO.getPhone();
String email = userRegisterDTO.getEmail(); String email = userRegisterDTO.getEmail();
String studentId = userRegisterDTO.getStudentId();
if (StrUtil.isBlank(username)){
throw new UserException("用户名不能为空");
}
if (StrUtil.isBlank(password)){ if (StrUtil.isBlank(password)){
throw new UserException("密码不能为空"); throw new UserException("密码不能为空");
} }
@ -42,12 +38,12 @@ public class ValidateUserUtil {
int cnt = 0; int cnt = 0;
if(StrUtil.isNotBlank(phone)) cnt++; if(StrUtil.isNotBlank(phone)) cnt++;
if(StrUtil.isNotBlank(email)) cnt++; if(StrUtil.isNotBlank(email)) cnt++;
if(StrUtil.isNotBlank(studentId)) cnt++; if(StrUtil.isNotBlank(username)) cnt++;
if (cnt == 0) { if (cnt == 0) {
throw new UserException("必须填写手机号、邮箱或学号其中一种注册方式"); throw new UserException("必须填写手机号、邮箱或用户名其中一种注册方式");
} }
if (cnt > 1) { if (cnt > 1) {
throw new UserException("只能选择一种注册方式(手机/邮箱/学号"); throw new UserException("只能选择一种注册方式(手机/邮箱/用户名");
} }
// 格式校验 // 格式校验
validateFormats(userRegisterDTO); validateFormats(userRegisterDTO);
@ -60,7 +56,6 @@ public class ValidateUserUtil {
String password = userRegisterDTO.getPassword(); String password = userRegisterDTO.getPassword();
String phone = userRegisterDTO.getPhone(); String phone = userRegisterDTO.getPhone();
String email = userRegisterDTO.getEmail(); String email = userRegisterDTO.getEmail();
String studentId = userRegisterDTO.getStudentId();
// 仅对非空字段做格式校验 // 仅对非空字段做格式校验
if (userMapper.exists(Wrappers.<User>lambdaQuery() if (userMapper.exists(Wrappers.<User>lambdaQuery()
.eq(User::getUsername, username))) { .eq(User::getUsername, username))) {
@ -69,14 +64,13 @@ public class ValidateUserUtil {
if(!password.matches(PASSWORD_REGEX)){ if(!password.matches(PASSWORD_REGEX)){
throw new UserException("密码格式错误"); throw new UserException("密码格式错误");
} }
validateUserFlag(phone, email, studentId, null); validateUserFlag(phone, email, null);
} }
public void validateFormats(UserChangeInfoDTO userChangeInfoDTO, Long currentUserId){ public void validateFormats(UserChangeInfoDTO userChangeInfoDTO, Long currentUserId){
String username = userChangeInfoDTO.getUsername(); String username = userChangeInfoDTO.getUsername();
String phone = userChangeInfoDTO.getPhone(); String phone = userChangeInfoDTO.getPhone();
String email = userChangeInfoDTO.getEmail(); String email = userChangeInfoDTO.getEmail();
String studentId = userChangeInfoDTO.getStudentId();
// String college = userChangeInfoDTO.getCollege(); // String college = userChangeInfoDTO.getCollege();
if (userMapper.exists(Wrappers.<User>lambdaQuery() if (userMapper.exists(Wrappers.<User>lambdaQuery()
.eq(User::getUsername, userChangeInfoDTO.getUsername()) .eq(User::getUsername, userChangeInfoDTO.getUsername())
@ -84,10 +78,10 @@ public class ValidateUserUtil {
throw new UserException("用户名已被使用"); throw new UserException("用户名已被使用");
} }
validateUserFlag(phone, email, studentId, currentUserId); validateUserFlag(phone, email, currentUserId);
} }
private void validateUserFlag(String phone, String email, String studentId, Long currentUserId) { private void validateUserFlag(String phone, String email, Long currentUserId) {
if(StrUtil.isNotBlank(phone)){ if(StrUtil.isNotBlank(phone)){
if(!phone.matches(PHONE_REGEX)) if(!phone.matches(PHONE_REGEX))
throw new UserException("手机号格式错误"); throw new UserException("手机号格式错误");
@ -106,15 +100,6 @@ public class ValidateUserUtil {
throw new UserException("邮箱已存在"); throw new UserException("邮箱已存在");
} }
} }
if(StrUtil.isNotBlank(studentId)){
if(!studentId.matches(STUDENTID_REGEX))
throw new UserException("学号格式错误");
if (userMapper.exists(Wrappers.<User>lambdaQuery()
.eq(User::getStudentId, studentId)
.ne(currentUserId != null, User::getId, currentUserId))) {
throw new UserException("学号已存在");
}
}
} }
} }

@ -2,11 +2,11 @@
lj: lj:
db: db:
host: localhost host: localhost
password: 1243969857 password: 123456
redis: redis:
host: localhost host: localhost
port: 6379 port: 6379
password: 1243969857 password: 123456
rabbitmq: rabbitmq:
host: localhost host: localhost
port: 15672 port: 15672

@ -2,11 +2,11 @@
lj: lj:
db: db:
host: localhost host: localhost
password: 1243969857 password: 123456
redis: redis:
host: localhost host: localhost
port: 6379 port: 6379
password: 1243969857 password: 123456
rabbitmq: rabbitmq:
host: localhost host: localhost
port: 15672 port: 15672

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save