当前位置: 首页 > wzjs >正文

wordpress自动切换手机主题宁波seo外包优化

wordpress自动切换手机主题,宁波seo外包优化,java做网站后台,朝阳区住房建设委网站在实战开发中,我们经常用到图形校验,具体怎么实现的呢? 安装模块 需要用到的模块有 svg-captcha #图形模块 uuid #随机id模块 redis #redis缓存数据 #最后还有 class-transformer class-validator #两个格式校验pipe模块 链接redis 我们把生成的图形答案需要放到redis中,这样…

在实战开发中,我们经常用到图形校验,具体怎么实现的呢?

安装模块

需要用到的模块有

svg-captcha #图形模块
uuid #随机id模块
redis #redis缓存数据
#最后还有
class-transformer class-validator #两个格式校验pipe模块

链接redis

我们把生成的图形答案需要放到redis中,这样的话,可以保证验证码的安全性和跨进程共享的特点

我们先创建一个nest的项目

使用nest g mo redis --no-spec 创建一个redis.module.ts [用来链接redis的配置]

创建一个redis.constants.ts [用来编写redis的签名,就是类似于enum的作用]

使用nest g s redis --no-spec 创建一个redis.service.ts [用来封装我们的redis的操作,但此项目中,并没有使用] 可以忽略

我们安装了redis 模块, 就可以使用动态模块的方式注入redis的链接配置了

对了,此处我用的是docker的redis的镜像

import { Global, Module } from '@nestjs/common';
import { RedisService } from './redis.service';
import { createClient } from 'redis';const createRedisClient = async () => {const client = createClient({socket: {host: '127.0.0.1',port: 6379,},});await client.connect();return client;
};@Global()  // 设置为全局模块,其他模块无需重复引入
@Module({providers: [{provide: 'REDIS_CLIENT',useFactory: createRedisClient,}, RedisService],exports: [RedisService, 'REDIS_CLIENT'],
})
export class RedisModule {
}

这里的话,是我们的constants签名文件 ,一些内容,我不方便直接硬编码,和TS的enum一样的其实

export const REDIS_CAPTCHA_PREFIX = 'captcha:';
export const REDIS_USER_SESSION_PREFIX = 'session:';
export const REDIS_SMS_CODE_PREFIX = 'sms:';

生成校验 svg

然后我们现在来书写生成图片和校验图片的代码

这里的generateCaptcha 方法使用来生成图片的

它主要做了什么?

  1. 使用svgCaptcha模块的create生成图片(含图片配置)
  2. 使用uuid,然后结合uuid和我们的签名,生成一个永不重复的id,到时候用来存在redis里
  3. 保存我们的svg的图片的code到redis里设置5分钟后过期,这样不用了他就会自动删除
  4. 最后返回我们的captchaId和图片,这里是因为,id的话,我们后续校验的时候需要,所以你必须给前端,图片的话,是我们用来渲染显示的,所以你也得给

还有一个validateCaptcha方法

它做了什么?

  1. 从前端的请求头里拿到我们刚刚生成图形时候给的结合版id
  2. 拿到我们的input 的图形码
  3. 然后拿着id去找redis里的缓存进行对比
  4. 正确了,就返回 true
  5. 失败了,就删除我们的key,然后等它分钟,redis里的会自己删除的
import { Inject, Injectable } from '@nestjs/common';
import * as svgCaptcha from 'svg-captcha';  //图片生成
import { v4 as uuidv4 } from 'uuid'; //uuid
import { REDIS_CAPTCHA_PREFIX } from '../redis/redis.constants';  //签名
import { RedisClientType } from 'redis'; //使用redis@Injectable()
export class CaptchaService {// 注入redis@Inject('REDIS_CLIENT')private redisClient: RedisClientType;// 生成图片方法async generateCaptcha() {// 生成图片const captcha = svgCaptcha.create({size: 4, // 验证码长度noise: 2, // 干扰线color: true, // 彩色文字background: '#cc9966',width: 120,height: 40,});// 随机生成一个uuidconst captchaId = uuidv4();// 使用uuid结合签名生成一个key,用来保存到redisconst key = `${REDIS_CAPTCHA_PREFIX}${captchaId}`;// 保存到redis// set(key,value,options)await this.redisClient.set(key, captcha.text, {// 过期时间等配置expiration: {type: 'EX',value: 300,},});return {// captcha,captchaId,svg: captcha.data,};}// 校验方法// 从前端的header中拿到idasync validateCaptcha(captchaId: string, userInput: string): Promise<boolean> {const key = `${REDIS_CAPTCHA_PREFIX}${captchaId}`;const value = await this.redisClient.get(key);if (!value) return false;// 删除验证码(防止复用)await this.redisClient.del(key);return value.toLowerCase() === userInput.toLowerCase();}}

前端路由 

这里做的主要就是图形生成请求和校验请求处理

  • 我们请求图形后,我们给配置它的header信息,保存我们的结合id
  • 校验的时候,就是我说的,从header里拿到id 和我们input的value和redis里的对比即可
import { Body, Controller, Get, HttpException, HttpStatus, Post, Res } from '@nestjs/common';
import { CaptchaService } from './captcha.service';
import { Response } from 'express';
import { ValidateCaptchaDto } from './dto/validate-captcha.dto';@Controller('captcha')
export class CaptchaController {constructor(private readonly captchaService: CaptchaService) {}@Get()async getCaptcha(@Res() res: Response) {// 生成,拿到两个东西const { captchaId, svg } = await this.captchaService.generateCaptcha();res.setHeader('Content-Type', 'image/svg+xml');res.setHeader('Captcha-Id', captchaId); // 把 captchaId 放到响应头里res.send(svg);  // ✅ 把 svg 图片直接作为返回体}// POST /captcha/verify@Post('verify')async verifyCaptcha(@Body() dto: ValidateCaptchaDto) {const isValid = await this.captchaService.validateCaptcha(dto.captchaId, dto.code);if (!isValid) {throw new HttpException('验证码错误或已过期', HttpStatus.BAD_REQUEST);}return {message: '验证码通过',};}}

 dto

我们请求时的dto对象

import { IsNotEmpty } from 'class-validator';export class ValidateCaptchaDto {@IsNotEmpty({ message: 'captchaId 不能为空' })captchaId: string;@IsNotEmpty({ message: '验证码不能为空' })code: string;
}

前端测试

main

main.js里要两个配置

一个是使用我们的校验包

一个是开启跨域

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from '@nestjs/common';async function bootstrap() {const app = await NestFactory.create(AppModule);app.useGlobalPipes(new ValidationPipe({whitelist: true,forbidNonWhitelisted: true,transform: true,}));app.enableCors({origin: true, // 或指定为 'http://localhost:5500' 之类你的 HTML 页面地址credentials: true,exposedHeaders: ['Captcha-Id'], // 非常关键!暴露自定义响应头});await app.listen(process.env.PORT ?? 3000);
}bootstrap();

index.html

一上来,先发一个请求,获取图形,并获取我们的节点,给他添加src属性

然后分别写了两个请求

这里逻辑很简单,自己看看吧

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><style>body {font-family: sans-serif;padding: 20px;}.captcha-box {display: flex;align-items: center;gap: 10px;margin-bottom: 10px;}.captcha-img {height: 40px;cursor: pointer;border: 1px solid #ccc;}</style>
</head>
<body><h2>图形验证码测试</h2><div class="captcha-box"><img id="captcha-img" class="captcha-img" title="点击刷新验证码" alt="显示失败" /><label for="code"><input type="text" id="code" placeholder="请输入验证码" /></label><button onclick="verifyCaptcha()">提交验证</button>
</div><p id="result"></p><script>let captchaId = '';// 加载验证码async function loadCaptcha() {try {const res = await axios.get('http://localhost:3000/captcha', {responseType: 'text',});const svg = res.data;console.log(svg);captchaId = res.headers['captcha-id'];const img = document.getElementById('captcha-img');img.src = 'data:image/svg+xml;base64,' + btoa(svg);} catch (err) {console.error('验证码加载失败:', err);alert('验证码加载失败');}}// 提交验证码校验async function verifyCaptcha() {const code = document.getElementById('code').value;try {const res = await axios.post('http://localhost:3000/captcha/verify', {captchaId,code,});document.getElementById('result').innerText = '✅ 验证成功';await loadCaptcha(); // 验证成功后刷新新验证码} catch (err) {document.getElementById('result').innerText = '❌ 验证失败或过期';await loadCaptcha(); // 验证失败后刷新新验证码}}// 点击图片刷新document.getElementById('captcha-img').addEventListener('click', loadCaptcha);// 初始化loadCaptcha();
</script></body>
</html>

这里展示的是最简单的,自己可以扩展一下使用短信验证等方式

http://www.dtcms.com/wzjs/93469.html

相关文章:

  • 众创空间网站建设网站seo优化推广外包
  • 徐州市城乡建设局官方网站深圳广告策划公司
  • 有哪些做ppt的网站有哪些免费com网站域名注册
  • 网站怎么建立数据库chrome google
  • 企业战略管理咨询公司北京seoqq群
  • 宣传网站怎么做的aso优化{ }贴吧
  • 石家庄网站建设服务百度推广电话客服24小时
  • 网站页面制作视频搜索引擎优化是指
  • 网站做贷款许可证百度关键词搜索查询
  • 百货批发网站建设网络营销师证书有用吗
  • 网站建设之开展电子商务网络推广营销方法
  • 惠州网站制作推广公司排名网络优化的三个方法
  • 做编程的 网站有哪些方面温州seo外包公司
  • 网站服务器的搭建免费下载百度软件
  • 做网站办什么类型营业执照优化大师是什么
  • 企业网站创建小结百度搜索风云榜
  • 太原市城乡建设局网站网站seo关键词排名推广
  • 成都网站建设科技公游戏推广平台代理
  • 搜索附近人软件沈阳seo搜索引擎
  • 可以做思维导图的网站宁波seo教学
  • 网站建设玖金手指排名14互联网营销师培训大纲
  • 网站的下拉列表怎么做沈阳网站制作优化推广
  • 施工企业农民工工资专项检查报告seo网络优化日常工作内容
  • 网站设计建设简历武汉seo价格
  • 做直播网站需要哪些技术百度推广助手手机版
  • 杭州建设银行网站首页怎么弄一个自己的网址
  • 威海外贸网站建设联系方式杭州seo公司哪家好
  • 网站建设的成功之处有哪些旅游景点推广软文
  • 重庆网站制作机构想做网站找什么公司
  • 帝国网站管理系统安装企业域名查询