Maison >Java >javaDidacticiel >Comment Springboot intègre easy-captcha pour réaliser l'affichage et la connexion du code de vérification d'image

Comment Springboot intègre easy-captcha pour réaliser l'affichage et la connexion du code de vérification d'image

王林
王林avant
2023-05-21 13:25:301426parcourir

1. Introduction à easy-captcha

easy-captcha est une bibliothèque de classes Java qui génère des codes de vérification graphiques. Elle prend en charge les types gif, chinois, arithmétique et autres, et peut être utilisée dans Java Web, JavaSE et d'autres projets.

Comment Springboot intègre easy-captcha pour réaliser laffichage et la connexion du code de vérification dimage

2. Ajouter des dépendances

<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. Écrire le code de la couche de 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.setContentType("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 value){
        localCache.put(key, value);
    }

    private String getCache(String key){

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

4. Développer une interface de code de vérification

Créer LoginController et fournir une méthode pour générer des codes de vérification

@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. pour afficher et générer du code Le code de vérification

<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=""
        />
      </template>
    </el-input>
  </el-form-item>
</Motion>

Le code complet de la page de connexion est le suivant

<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" / alt="Comment Springboot intègre easy-captcha pour réaliser l'affichage et la connexion du code de vérification d'image" >
    <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">
      <div class="img">
        <component :is="toRaw(illustration)" />
      </div>
      <div class="login-box">
        <div class="login-form">
          <avatar class="avatar" />
          <Motion>
            <h3 class="outline-none">{{ title }}</h3>
          </Motion>

          <el-form
            ref="ruleFormRef"
            :model="ruleForm"
            :rules="loginRules"
            size="large"
          >
            <Motion :delay="100">
              <el-form-item
                :rules="[
                  {
                    required: true,
                    message: &#39;请输入账号&#39;,
                    trigger: &#39;blur&#39;
                  }
                ]"
                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=""
                    />
                  </template>
                </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)"
              >
                登录
              </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>

Compilez et exécutez le backend Lorsque des collègues exécutent le frontend, vous pouvez voir la page de connexion.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer