开发者

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

目录
  • 1、easy-captcha简介
  • 2、添加依赖
  • 3、编写service层代码
  • 4、开发验证码接口
  • 5、前端vue增加如何代码显示生成的验证码

1、easy-captcha简介

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

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

2、添加依赖

<guava.version>20.0</guava.version>
<captcha.version>1.6.2</captcha.version>

<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>${guava.version}</version>
</dependency>

<dependency>
  <groupId>com.github.whvcse</groupId>
  <artifactId>easy-captcha</artifactId>
  <version>${captcha.version}</version>
</dependency>

3、编写service层代码

@Service
public class CaptchaServiceImpl implements CaptchaService {

  /**
  * Local Cache 5分钟过期
  */
  Cache<String, String> localCache = CacheBuilder.newBuilder().maximumSize(1000).expireAfterAccess(5, TimeUnit.MINUTES).build();

  @Override
  public void create(HttpServletResponse response, String uuid) throws IOException {
    response.setContentTyppythone("image/gif");
    response.setHeader("Pragma", "No-cache");
    response.setHeader("Cache-Control", "no-cache");
    response.setDateHeader("Expires", 0);

    //生成验证码
    SpecCaptcha captcha = new SpecCaptcha(150, 40);
    captcha.setLen(5);
    captcha.setCharType(Captcha.TYPE_DEFAULT);
    captcha.out(response.getOutputStream());

    //保存到缓存
    setCache(uuid, captcha.text());
  }

  @Override
  public boolean validate(String uuid, String code) {
    //获取验证码
    String captcha = getCache(uuid);

    //效验成功
    if(code.equalsIgnoreCase(captcha)){
      return true;
    }

    return false;
  }


  private void setCache(String key, String vgvUlAQluGvalue){
    localCache.put(key, value);
  }

  private String getCache(String key){

    String captcha = localCache.getIfPresent(key);
    //删除验证码
    if(captcha != null){
      localCache.invalidate(key);
    }
    return captcha;
  }
}

4、开发验证码接口

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

@Controller
@AllArgsConstructor
public class CaptchaController {
  private CaptchaService captchaService;

  @GetMapping("/captcha")
  public void captcha(HttpServletResponse response, String uuid)throws IOException {
    //uuid不能为空
    AssertUtils.isBlank(uuid, ErrorCode.IDENTIFIER_NOT_NULL);

    //生成验证码
    captchaService.create(response, uuid);
  }
}

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

<Motion :delay="200">
  <el-form-item prop="verifyCode">
    <el-input
      clearable
      v-model="ruleForm.verifyCode"
      placeholder="验证码"
      :prefix-icon="useRenderIcon(Line)"
    >
      <template v-slot:append>
        <img
          style="
            vertical-align: middle;
            height: 40px;
            width: 100px;
            cursor: pointer;
          "
          :src="captchaUrl"
          @click="onRefreshCode"
          alt="springboot 集成easy-captcha实现图像验证码显示和登录"
        />
      </template>
    </el-input>
  </el-form-item>
</Motion>

完整的登录页代码如下

<script setup lang="ts">
import Motion from "./utils/motion";
import { useRouter } from "vue-router";
import { message } from "@/utils/message";
import { loginRules } from "./utils/rule";
import { useNav } from "@/layout/hooks/useNav";
import type { FormInstance } from "element-plus";
import { useLayout } from "@/layout/hooks/useLayout";
import { useUserStoreHook } from "@/store/modules/user";
import { bg, avatar, illustration } from "./utils/static";
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import { ref, reactive, toRaw, onMounted, onBeforeUnmount } from "vue";
import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";
import { initRouter } from "@/router/utils";
import { getUuid } from "@/utils/utils";
import dayIcon from "@/assets/svg/day.svg?component";
import darkIcon from "@/assets/svg/dark.svg?component";
import Lock from "@iconify-icons/ri/lock-fill";
import User from "@iconify-icons/ri/user-3-fill";
import Line from "@iconify-icons/ri/shield-keyhole-line";
import { getConfig } from "@/config";

defineOptions({
 name: "Login"
});
const router = useRouter();
const loading = ref(false);
const ruleFormRef = ref<FormInstance>();
const captchaUrl = ref("");
const { Api } = getConfig();

const { initStorage } = useLayout();
initStorage();

const { dataTheme, dataThemeChange } = useDataThemeChange();
dataThemeChange();
const { title } = useNav();

const ruleForm = reactive({
 username: "admin",
 password: "admin123",
 verifyCode: "",
 uuid: ""
});

const onLogin = async (formEl: FormInstance | undefined) => {
 loading.value = true;
 if (!formEl) return;
 await formEl.validate((valid, fields) => {
  if (valid) {
   useUserStoreHook()
    .loginByUsername({ username: ruleForm.username, password: "admin123" })
    .then(res => {
     if (res.code == 200) {
      // 获取后端路由
      initRouter().then(() => {
       router.push("/");
       message("登录成功", { type: "success" });
      });
     }
    });
  } else {
   loading.value = false;
   return fields;
  }
 });
};

/** 使用公共函数,避免`removeEventListener`失效 编程客栈*/
function onkeypress({ code }: KeyboardEvent) {
 if (code === "Enter") {
  onLogin(ruleFormRef.value);
 }
}
function getCaptchaUrl() {
 ruleForm.uuid = getUuid();
 captchaUrl.value = `${Api}/captcha?uuid=${ruleForm.uuid}`;
}
function onRefreshCode() {
 getCaptchaUrl();
}

onMounted(() => {
 window.document.addEventListener("keypress", onkeypress);
 getCaptchaUrl();
});

onBeforeUnmount(() => {
 window.document.removeEventListener("keypress", onkeypress);
});
</script>

<template>
 <div class="select-none">
  <img :src="bg" class="wave" />
  <div class="Flex-c absolute right-5 top-3">
   <!-- 主题 -->
   <el-switch
    v-model="dataTheme"
    inline-prompt
    :active-icon="dayIcon"
    :inactive-icon="darkIcon"
    @change="dataThemeChange"
   />
  </div>
  <div class="login-container">
   &l开发者_JAVAt;div class="img">
    <component :is="toRaw(illustration)" />
   </div>
   <div class="login-box">
    <div class="login-form">
     <avatar class="avatar" />
     <Motion>
      <h2 class="outline-none">{{ title }}</h2>
     </Motion>

     <el-form
      ref="ruleFormRef"
      :model="ruleForm"
      :rules="loginRules"
      size="large"
     >
      <Motion :delay="100">
       <el-form-item
        :rules="[
         {
          required: true,
          message: '请输入账号',
          trigger: 'blur'
         }
        ]"
        prop="username"
       >
        <el-input
         clearable
         v-model="ruleForm.username"
         placeholder="账号"
         :prefix-icon="useRenderIcon(User)"
        />
       </el-form-item>
      </Motion>

      <Motion :delay="150">
       <el-form-item prop="password">
        <el-input
         clearable
         show-password
         v-model="ruleForm.password"
         placeholder="密码"
         :prefix-icon="useRenderIcon(Lock)"
        />
       </el-form-item>
      </Motion>

      <Motion :delay="200">
       <el-form-item prop="verifyCode">
        <el-input
         clearable
         v-model="ruleForm.verifyCode"
         placeholder="验证码"
         :prefix-icon="useRenderIcon(Line)"
        >
         <template v-slot:append>
          <img
           style="
            vertical-align: middle;
            height: 40px;
            width: 100px;
            cursor: pointer;
           "
           :src="captchaUrl"
           @click="onRefreshCode"
           alt="springboot 集成easy-captcha实现图像验证码显示和登录"
          />
         </template>
   php     </el-input>
       </el-form-item>
      </Motion>

      <Motion :delay="250">
       <el-button
        class="w-full mt-4"
        size="default"
        type="primary"
        :loading="loading"
        @click="onLogin(ruleFormRef)"
       >
        登录www.devze.com
       </el-button>
      </Motion>
     </el-form>
    </div>
   </div>
  </div>
 </div>
</template>

<style scoped>
@import url("@/style/login.css");
</style>

<style lang="scss" scoped>
:deep(.el-input-group__append, .el-input-group__prepend) {
 padding: 0;
}
</style>

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

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新开发

开发排行榜