springboot 集成easy-captcha实现图像验证码显示和登录

1、easy-captcha简介

easy-captcha是生成图形验证码的Java类库,支持gif、中文、算术等类型,可用于Java Web、JavaSE等项目。参考地址:[https://github.com/whvcse/EasyCaptcha]

-1

2、添加依赖

  1. <guava.version>20.0</guava.version>
  2. <captcha.version>1.6.2</captcha.version>
  3.  
  4. <dependency>
  5.      <groupId>com.google.guava</groupId>
  6.      <artifactId>guava</artifactId>
  7.      <version>${guava.version}</version>
  8. </dependency>
  9.  
  10. <dependency>
  11.      <groupId>com.github.whvcse</groupId>
  12.      <artifactId>easy-captcha</artifactId>
  13.      <version>${captcha.version}</version>
  14. </dependency>

3、编写service层代码

  1. @Service
  2. public class CaptchaServiceImpl implements CaptchaService {
  3.  
  4.      /**
  5.      * Local Cache 5分钟过期
  6.      */
  7.      Cache<String, String> localCache = CacheBuilder.newBuilder().maximumSize(1000).expireAfterAccess(5, TimeUnit.MINUTES).build();
  8.  
  9.      @Override
  10.      public void create(HttpServletResponse response, String uuid) throws IOException {
  11.      response.setContentType(“image/gif”);
  12.      response.setHeader(“Pragma”, “No-cache”);
  13.      response.setHeader(“Cache-Control”, “no-cache”);
  14.      response.setDateHeader(“Expires”, 0);
  15.  
  16.      //生成验证码
  17.      SpecCaptcha captcha = new SpecCaptcha(150, 40);
  18.      captcha.setLen(5);
  19.      captcha.setCharType(Captcha.TYPE_DEFAULT);
  20.      captcha.out(response.getOutputStream());
  21.  
  22.      //保存到缓存
  23.      setCache(uuid, captcha.text());
  24.      }
  25.  
  26.      @Override
  27.      public boolean validate(String uuid, String code) {
  28.      //获取验证码
  29.      String captcha = getCache(uuid);
  30.  
  31.      //效验成功
  32.      if(code.equalsIgnoreCase(captcha)){
  33.          return true;
  34.      }
  35.  
  36.      return false;
  37.      }
  38.  
  39.  
  40.      private void setCache(String key, String value){
  41.      localCache.put(key, value);
  42.      }
  43.  
  44.      private String getCache(String key){
  45.  
  46.      String captcha = localCache.getIfPresent(key);
  47.      //删除验证码
  48.      if(captcha != null){
  49.          localCache.invalidate(key);
  50.      }
  51.      return captcha;
  52.      }
  53. }

4、开发验证码接口

创建LoginController并提供生成验证码的方法

  1. @Controller
  2. @AllArgsConstructor
  3. public class CaptchaController {
  4.      private CaptchaService captchaService;
  5.  
  6.      @GetMapping(“/captcha”)
  7.      public void captcha(HttpServletResponse response, String uuid)throws IOException {
  8.      //uuid不能为空
  9.      AssertUtils.isBlank(uuid, ErrorCode.IDENTIFIER_NOT_NULL);
  10.  
  11.      //生成验证码
  12.      captchaService.create(response, uuid);
  13.      }
  14. }

5、前端vue增加如何代码显示生成的验证码

  1. <Motion :delay=“200”>
  2.      <el-form-item prop=“verifyCode”>
  3.      <el-input
  4.          clearable
  5.          v-model=“ruleForm.verifyCode”
  6.          placeholder=“验证码”
  7.          :prefix-icon=“useRenderIcon(Line)”
  8.      >
  9.          <template v-slot:append>
  10.          <img
  11.              style=
  12.              verticalalign: middle;
  13.              height: 40px;
  14.              width: 100px;
  15.              cursor: pointer;
  16.              
  17.              :src=“captchaUrl”
  18.              @click=“onRefreshCode”
  19.              alt=“springboot 集成easy-captcha实现图像验证码显示和登录”
  20.          />
  21.          </template>
  22.      </el-input>
  23.      </el-form-item>
  24. </Motion>

完整的登录页代码如下

  1. <script setup lang=“ts”>
  2. import Motion from “./utils/motion”;
  3. import { useRouter } from “vue-router”;
  4. import { message } from “@/utils/message”;
  5. import { loginRules } from “./utils/rule”;
  6. import { useNav } from “@/layout/hooks/useNav”;
  7. import type { FormInstance } from “element-plus”;
  8. import { useLayout } from “@/layout/hooks/useLayout”;
  9. import { useUserStoreHook } from “@/store/modules/user”;
  10. import { bg, avatar, illustration } from “./utils/static”;
  11. import { useRenderIcon } from “@/components/ReIcon/src/hooks”;
  12. import { ref, reactive, toRaw, onMounted, onBeforeUnmount } from “vue”;
  13. import { useDataThemeChange } from “@/layout/hooks/useDataThemeChange”;
  14. import { initRouter } from “@/router/utils”;
  15. import { getUuid } from “@/utils/utils”;
  16. import dayIcon from “@/assets/svg/day.svg?component”;
  17. import darkIcon from “@/assets/svg/dark.svg?component”;
  18. import Lock from “@iconify-icons/ri/lock-fill”;
  19. import User from “@iconify-icons/ri/user-3-fill”;
  20. import Line from “@iconify-icons/ri/shield-keyhole-line”;
  21. import { getConfig } from “@/config”;
  22.  
  23. defineOptions({
  24.      name: “Login”
  25. });
  26. const router = useRouter();
  27. const loading = ref(false);
  28. const ruleFormRef = ref<FormInstance>();
  29. const captchaUrl = ref(“”);
  30. const { Api } = getConfig();
  31.  
  32. const { initStorage } = useLayout();
  33. initStorage();
  34.  
  35. const { dataTheme, dataThemeChange } = useDataThemeChange();
  36. dataThemeChange();
  37. const { title } = useNav();
  38.  
  39. const ruleForm = reactive({
  40.      username: “admin”,
  41.      password: “admin123”,
  42.      verifyCode: “”,
  43.      uuid: “”
  44. });
  45.  
  46. const onLogin = async (formEl: FormInstance | undefined) => {
  47.      loading.value = true;
  48.      if (!formEl) return;
  49.      await formEl.validate((valid, fields) => {
  50.      if (valid) {
  51.      useUserStoreHook()
  52.      .loginByUsername({ username: ruleForm.username, password: “admin123” })
  53.      .then(res => {
  54.          if (res.code == 200) {
  55.          // 获取后端路由
  56.          initRouter().then(() => {
  57.          router.push(“/”);
  58.          message(“登录成功”, { type: “success” });
  59.          });
  60.          }
  61.      });
  62.      } else {
  63.      loading.value = false;
  64.      return fields;
  65.      }
  66.      });
  67. };
  68.  
  69. /** 使用公共函数,避免`removeEventListener`失效 */
  70. function onkeypress({ code }: KeyboardEvent) {
  71.      if (code === “Enter”) {
  72.      onLogin(ruleFormRef.value);
  73.      }
  74. }
  75. function getCaptchaUrl() {
  76.      ruleForm.uuid = getUuid();
  77.      captchaUrl.value = `${Api}/captcha?uuid=${ruleForm.uuid}`;
  78. }
  79. function onRefreshCode() {
  80.      getCaptchaUrl();
  81. }
  82.  
  83. onMounted(() => {
  84.      window.document.addEventListener(“keypress”, onkeypress);
  85.      getCaptchaUrl();
  86. });
  87.  
  88. onBeforeUnmount(() => {
  89.      window.document.removeEventListener(“keypress”, onkeypress);
  90. });
  91. </script>
  92.  
  93. <template>
  94.      <div class=“select-none”>
  95.      <img :src=“bg” class=“wave” />
  96.      <div class=Flex-c absolute right-5 top-3″>
  97.      <!– 主题 –>
  98.      <el-switch
  99.      v-model=“dataTheme”
  100.      inline-prompt
  101.      :active-icon=“dayIcon”
  102.      :inactive-icon=“darkIcon”
  103.      @change=“dataThemeChange”
  104.      />
  105.      </div>
  106.      <div class=“login-container”>
  107.      <div class=“img”>
  108.      <component :is=“toRaw(illustration)” />
  109.      </div>
  110.      <div class=“login-box”>
  111.      <div class=“login-form”>
  112.          <avatar class=“avatar” />
  113.          <Motion>
  114.          <h2 class=“outline-none”>{{ title }}</h2>
  115.          </Motion>
  116.  
  117.          <el-form
  118.          ref=“ruleFormRef”
  119.          :model=“ruleForm”
  120.          :rules=“loginRules”
  121.          size=“large”
  122.          >
  123.          <Motion :delay=“100”>
  124.          <el-form-item
  125.          :rules=“[
  126.              {
  127.              required: true,
  128.              message: ‘请输入账号’,
  129.              trigger: ‘blur’
  130.              }
  131.          ]”
  132.          prop=“username”
  133.          >
  134.          <el-input
  135.              clearable
  136.              v-model=“ruleForm.username”
  137.              placeholder=“账号”
  138.              :prefix-icon=“useRenderIcon(User)”
  139.          />
  140.          </el-form-item>
  141.          </Motion>
  142.  
  143.          <Motion :delay=“150”>
  144.          <el-form-item prop=“password”>
  145.          <el-input
  146.              clearable
  147.              show-password
  148.              v-model=“ruleForm.password”
  149.              placeholder=“密码”
  150.              :prefix-icon=“useRenderIcon(Lock)”
  151.          />
  152.          </el-form-item>
  153.          </Motion>
  154.  
  155.          <Motion :delay=“200”>
  156.          <el-form-item prop=“verifyCode”>
  157.          <el-input
  158.              clearable
  159.              v-model=“ruleForm.verifyCode”
  160.              placeholder=“验证码”
  161.              :prefix-icon=“useRenderIcon(Line)”
  162.          >
  163.              <template v-slot:append>
  164.              <img
  165.              style=
  166.              verticalalign: middle;
  167.              height: 40px;
  168.              width: 100px;
  169.              cursor: pointer;
  170.              
  171.              :src=“captchaUrl”
  172.              @click=“onRefreshCode”
  173.              alt=“springboot 集成easy-captcha实现图像验证码显示和登录”
  174.              />
  175.              </template>
  176.      </el-input>
  177.          </el-form-item>
  178.          </Motion>
  179.  
  180.          <Motion :delay=“250”>
  181.          <el-button
  182.          class=“w-full mt-4”
  183.          size=“default”
  184.          type=“primary”
  185.          :loading=“loading”
  186.          @click=“onLogin(ruleFormRef)”
  187.          >
  188.          登录
  189.          </el-button>
  190.          </Motion>
  191.          </el-form>
  192.      </div>
  193.      </div>
  194.      </div>
  195.      </div>
  196. </template>
  197.  
  198. <style scoped>
  199. @import url(“@/style/login.css);
  200. </style>
  201.  
  202. <style lang=“scss” scoped>
  203. :deep(.elinputgroup__append, .elinputgroup__prepend) {
  204.      padding: 0;
  205. }
  206. </style>

编译运行后端,同事运行点前端,可以看到登录页面。

到此这篇关于springboot 集成easy-captcha实现图像验证码显示和登录的文章就介绍到这了,更多相关springboot easy-captcha验证码内容请搜索我们以前

标签

发表评论