Spring Boot实现登录验证码功能的案例详解
简介
最近,我在开发一个基于Spring Boot的Web应用程序时,需要实现一个登录验证码功能,以确保用户输入有效并防止暴力破解。在研究后,我发现可以通过添加一些依赖项和编写一些代码来轻松地实现此功能。在本文中,我将与您分享实现登录验证码功能的详细步骤。
步骤
步骤1:添加依赖
为了实现登录验证码功能,我们需要在Spring Boot项目中添加以下依赖项:
<!-- Spring Boot Web Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Thymeleaf Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- Spring Boot Validation Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- Google Guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency>
<!-- Google Guava图像处理库 -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava-image</artifactId>
<version>19.0</version>
</dependency>
<!-- 生成随机数工具 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.2.1</version>
</dependency>
步骤2:创建验证码API
为了创建验证码API,我们需要在Spring Boot应用程序中创建一个REST API Endpoint。我们将使用Google Guava创建验证码图像,并将其返回到客户端。以下是我们创建的验证码API:
@RestController
@RequestMapping("/api/v1")
public class CaptchaApiController {
private final int WIDTH = 100;
private final int HEIGHT = 35;
private final int LENGTH = 4;
private final Cache<String, String> cache = CacheBuilder.newBuilder().maximumSize(1000).build();
@GetMapping(value = "/captcha", produces = MediaType.IMAGE_JPEG_VALUE)
public ResponseEntity<byte[]> createCaptcha(HttpServletResponse response) throws Exception {
String captcha = RandomStringUtils.randomAlphanumeric(LENGTH);
byte[] bytes = createCaptchaImage(captcha);
cache.put(captcha.toLowerCase(), captcha.toLowerCase());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_JPEG);
headers.setContentLength(bytes.length);
return new ResponseEntity<>(bytes, headers, HttpStatus.OK);
}
@GetMapping("/captcha/check")
public boolean checkCaptcha(@RequestParam String captcha) {
return Strings.isNullOrEmpty(captcha) || !captcha.matches("[a-zA-Z0-9]{4}") || !cache.asMap().containsKey(captcha.toLowerCase());
}
private byte[] createCaptchaImage(String captchaText) throws IOException {
BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
Graphics graphics = image.getGraphics();
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, WIDTH, HEIGHT);
graphics.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 22));
for (int i = 0; i < captchaText.length(); i++) {
graphics.setColor(new Color((int) (Math.random() * 255), (int) (Math.random() * 255), (int) (Math.random() * 255)));
graphics.drawString(Character.toString(captchaText.charAt(i)), 15 * i + 5, 20 + (int) (10 * Math.random()));
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(image, "jpeg", outputStream);
return outputStream.toByteArray();
}
}
根据以上代码,我们可以看到 createCaptcha
返回一个byte数组,这是使用Java的内置API实现验证码图像生成的数据,利用响应头指定响应数据格式为JPEG,它可用作REST服务API进行调用。另外,我们还可以看到 checkCaptcha
用于验证验证码是否匹配。
步骤3:创建验证码表单
我们需要将验证码添加到登录表单中,以便用户输入验证码。以下是我们创建的登录表单:
<form method="post" action="/login">
<div>
<label for="username">用户名 :</label>
<input id="username" type="text" placeholder="请输入用户名" name="username" required="required"/>
</div>
<div>
<label for="password">密码 :</label>
<input id="password" type="password" placeholder="请输入密码" name="password" required="required"/>
</div>
<div>
<label for="captcha">验证码 :</label>
<input id="captcha" type="text" placeholder="请输入验证码" name="captcha" required="required"/>
<img id="captcha-img" alt="验证码" src="/api/v1/captcha"/>
</div>
<button type="submit">登录</button>
</form>
在上面的表单中,我们添加了一个图像元素到 img
标记并使用 src
属性设置图像URL。在加载页面时,将调用 api / v1 / captcha
端点来获取验证码图像。除此之外,我们还添加了一个输入框来让用户输入验证码。
步骤4:验证用户
最后,我们需要创建另一个Endpoint,以验证用户输入的用户名、密码和验证码是否正确。以下是我们创建的验证代码:
@PostMapping("/login")
public ModelAndView login(@RequestParam String username, @RequestParam String password, @RequestParam String captcha, HttpSession session) {
ModelAndView modelAndView = new ModelAndView();
boolean validCaptcha = !checkCaptcha(captcha);
boolean validUser = userRepository.existsByUsername(username) && passwordEncoder.matches(password, userRepository.findByUsername(username).getPassword());
if (validCaptcha && validUser) {
session.setAttribute("username", username);
modelAndView.setViewName("redirect:/dashboard");
} else {
modelAndView.clear();
modelAndView.setViewName("redirect:/login");
modelAndView.addObject("errorMessage", "用户名或密码错误");
}
return modelAndView;
}
在上述代码中,我们首先验证验证码是否与 captcha
相同,如果相同,则通过验证。如果验证码验证通过,则验证用户的用户名和密码。如果验证通过,则将其添加到当前会话中,然后将用户重定向到仪表板页面。
示例
为了更好地说明博客文章的内容,请参见以下两个互联网示例::
这些示例提供了一个Spring Boot应用程序,帮助您快速获取有关如何实现登录验证码功能的真实和具体的实现。
结论
在本文中,我们详细探讨了Spring Boot实现图形验证码的方法,并提供了两个示例代码引用供读者参考。使用Spring Boot和其他依赖项,我们可以轻松地实现网站中的验证码功能,以降低暴力攻击和垃圾回收的风险。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Boot实现登录验证码功能的案例详解 - Python技术站