Vue Springboot (包括后端解决跨域)实现登录验证码功能详细完整版
利用Hutool 基于Vue、ElementUI、Springboot (跨域)实现登录验证码功能
前言
提示:实现此功能建立在你至少能够基础使用vue、elementui、springboot
一、Hutool是什么?
工欲善其事必先利其器! Hutool 就是这么一款超级强力的工具类。
在大家日常工作中,都常常会做如下这些非常繁琐的工作:
- 日期与字符串转换
- 文件操作
- 转码与反转码
- 随机数生成
- 压缩与解压
- 编码与解码
- CVS文件操作
- 缓存处理
- 加密解密
- 定时任务
- 邮件收发
- 二维码创建
- FTP 上传与下载
- 图形验证码生成
等等等等…
以上这些事情,要么自己动手写代码,要么从零零碎碎的各个不同的地方去找各种零零散散的代码来改造成自己需要的样子。
现在不用了,您只需要一个 hutool 那么这些功能都是现成滴了,而且非常好用。。
想去使用了解的我这里给个传送门
二、下面开始步入正题:使用步骤
1.先引入Hutool依赖
可全部引入,也可以引入部分,我这里就全部引入了:
<!-- 在pom.xml文件中引入hutool -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.2.5</version>
</dependency>
2.控制层
我这里先讲一下思路:
前端发起一个请求,后端控制层利用hutool编写生成验证码的代码,并将验证码的内容保存到session中,在登录控制层中获取这个session的值,与当前登录前端输入的验证码的值对比,若相同则验证成功,既可以执行后面的操作,若不相同,则要返回并提示验证码错误。
下面是控制层代码:
//生成验证码
@GetMapping("/api/getCode")
public void getCode(HttpServletResponse response, HttpSession session) throws IOException {
// 定义图形验证码的长、宽、验证码位数、线性数量
//还有更多功能自行研究,这里只做简单实现
LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(125, 50,4,5);
//保存到session
session.setAttribute("code", lineCaptcha.getCode());
//响应输出流
ServletOutputStream outputStream = response.getOutputStream();
//将生成的验证码图片通过流的方式返回给前端
ImageIO.write(lineCaptcha.getImage(), "JPEG", outputStream);
}
下面再是登录控制,因为我这里是用了shiro,不懂shiro的可以自行百度,不过其实也不用管,重点看验证码实现,然后再结合自己业务使用。
//登录控制
@PostMapping("/api/login")
public Result login(@RequestBody User requestUser,HttpSession session) {
//获得存储在session中的验证码(不会shiro的不用管,看这有关验证码的就行)
String sessionCheckCode = (String) session.getAttribute("code");
//防XFS HtmlUtils.htmlEscape(username);
String username = requestUser.getUsername();
username = HtmlUtils.htmlEscape(username);
Subject subject = SecurityUtils.getSubject();
//判断验证码是否与前端输入的值相同 (不会shiro的不用管,看这有关验证码的就行)
if (requestUser.getCaptcha() != null && sessionCheckCode.equals(requestUser.getCaptcha())) {
//移除验证码
session.removeAttribute("code");
//验证认证状态
if (!subject.isAuthenticated()) {
// 组装一个token
UsernamePasswordToken token = new UsernamePasswordToken(username, requestUser.getPassword());
// 开启记住我功能
if (requestUser.isRememberMe()) {
token.setRememberMe(true);
}
try {
//验证成功 做认证
subject.login(token);
User user = userService.findByUsername(username);
if (!user.isEnabled()) {
return ResultFactory.buildFailResult("该用户已被禁用");
}
return ResultFactory.buildSuccessResult(username);
} catch (IncorrectCredentialsException e) {
return ResultFactory.buildFailResult("密码错误");
} catch (UnknownAccountException e) {
return ResultFactory.buildFailResult("账号不存在");
}
}
}
return ResultFactory.buildFailResult("验证码不正确");
}
写到这里,还是把实体类也提供一下吧,好人做到底。
提示:我这里用了jpa、lombok你们不用管。就里面放了一个属性存放验证码。
详细里面都写了
package top.wangxingjun.separate.entity;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.*;
import org.hibernate.validator.constraints.Length;
import javax.persistence.*;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;
import java.util.List;
/**
* 用户类
*
* @author wxj
* @Date 2020/8/10
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Table(name = "user")
@ToString
@JsonIgnoreProperties({"handler","hibernateLazyInitializer"})
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;
/**
* Username.
*/
@NotEmpty(message = "账号不能为空")
private String username;
/**
* Password.
*/
@NotEmpty(message = "密码不能为空")
@Length(min = 3,message = "密码长度不能低于3位")
private String password;
/**
* Salt for encoding.
*/
private String salt;
/**
* Real name.
*/
private String name;
/**
* Phone number.
*/
@NotEmpty(message = "手机号码不能为空")
@Pattern(regexp = "^1[3456789]\\d{9}$",message = "手机格式不正确")
private String phone;
/**
* Email address.
*
* A Email address can be null,but should be correct if exists.
*/
@NotEmpty(message = "邮箱不能为空")
@Email(message = "请输入正确的邮箱")
private String email;
/**
* User status.
*/
private boolean enabled;
/**
* Transient property for storing role owned by current user.
*/
@Transient
private List<AdminRole> roles;
@Transient
//看这个属性就行 我这里使用了注解,所以不用写getter/setter方法,你们没用上的当然得自己手动生成
private String captcha;//验证码
/**
* Transient property for rememberMe pwd by current user.
*/
@Transient
private boolean rememberMe;//记住我
}
3.下面到前端登录界面
这里我只贴关键代码
<el-form-item>
<span class="svg-container svg-container_login">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-yanzhengma"></use>
</svg>
</span>
<el-input
v-model="loginForm.captcha"
placeholder="验证码"
clearable
style="width:42%;"
maxlength="4"
/>
<a href="javascript:void(0)" @click="createCode()"
><img :src="verifitycode" style="width:20%;" alt="图片加载失败"
/></a>
</el-form-item>
下面是data、mounted() 、methods中相关代码:
data() {
return {
loginForm: {
username: "admin",
password: "",
captcha: "",
rememberMe: false
},
verifitycode: ""
};
},
mounted() {
//相当于初始化
this.createCode();
},
methods: {
//获取验证码
createCode() {
//二进制方式读取图片流 验证码
this.$axios
.get("/getCode", {
responseType: "arraybuffer"
})
.then(response => {
return (
"data:image/png;base64," +
btoa(
new Uint8Array(response.data).reduce(
(data, byte) => data + String.fromCharCode(byte),""
)
)
);
})
.then(data => {
this.verifitycode = data;
});
}
上面最核心的便是通过二进制流的方式获取后端返回回来的图片验证码,当然前后端返利肯定还牵扯到跨域问题,跨域解决方式有几种。咳咳,咋又扯到这了,额…好吧。那我也把我后端跨域解决的部分贴出来吧(还可以用注解的方式@CrossOrigin,自行了解),我这里使用重写WebMvcConfigurer方式进行CORS实现跨域访问。
package top.wangxingjun.separate.config;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.web.servlet.config.annotation.*;
/**
* @author wxj
* @Date 2020/8/10
*/
@SpringBootConfiguration
public class MyWebConfigurer implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
//所有请求都允许跨域,使用这种配置方法就不能在 interceptor 中再配置 header 了
registry.addMapping("/**")
.allowCredentials(true)
.allowedOrigins("*")
.allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
.allowedHeaders("*")
.maxAge(3600);
}
}
好了~结束
Vue Springboot (包括后端解决跨域)实现登录验证码功能详细完整版的更多相关文章
- Nginx反向代理和Node.js后端解决跨域问题
最近在写自己的博客,涉及到跨域的问题,自己捣鼓许久,终于解决了.然后总结一下,记录一下,日后遇到类似的问题的时候也可以得到一些启发. 一.什么是跨域 跨域,指的是浏览器不能执行其他网站的脚本.它是由浏 ...
- express搭建后端请求路由,前端进行访问对应的接口 后端解决跨域
代码在 ==>E:\nodes实战\myserve\testserve 1 express搭建后端请求路由,前端进行访问对应的接口 1) 创建项目目录 express 项目名 -e 然后按照提示 ...
- SpringBoot使用CORS解决跨域请求问题
什么是跨域? 同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源. 同源策略是浏览器安全的基石. 如果一个请求地址里面的协议.域名和端口号都相同,就属于同源. ...
- SpringBoot配置Cors解决跨域请求问题
一.同源策略简介 同源策略[same origin policy]是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源. 同源策略是浏览器安全的基石. 什么是源 源[or ...
- vue反向代理(解决跨域)
1,vue中有提供反向代理的接口,就是config/index.js中的proxyTable,我的脚手架版本是2.9.6,proxyTable配置初始为空,如下图. 2,将proxyTable配置如下 ...
- Beego和Vue的前后端分离跨域问题处理
VUE封装的请求头(注意请求头,跨域要用到) 路径 utils/mereq.js import request from '@/utils/request' import qs from 'qs' e ...
- Springboot通过cors解决跨域问题(解决spring security oath2的/oauth/token跨域问题)
@Bean public CorsFilter corsFilter() { final UrlBasedCorsConfigurationSource source = new UrlBasedCo ...
- 解决跨域POST登录中IE不能正常工作的bug
结合我的这篇blog <简单实用的跨域表单POST提交> 文章,这篇blog中的思路是解决在www.a.com站中登录 同时要把关联站www.b.com登录状态也设置成登录状态,在a中获取 ...
- vue配置请求转发解决跨域问题
通过nodejs的请求转发到后台,前端地址:http://localhost:8080 后端地址:http://localhost:8081 vue.config.js内容如下: let prox ...
随机推荐
- sql中的字符串拼接
转载自:https://www.cnblogs.com/rainman/p/6203065.html 1. 概述 在SQL语句中经常需要进行字符串拼接,以sqlserver,oracle,mysql三 ...
- Shell脚本实现---Swarm集群部署实例(Swarm Cluster)
Shell脚本实现---Swarm集群部署实例(Swarm Cluster) 一.机器环境(均是centos7.8) IP hostname 角色 192.168.10.200 manager-swa ...
- Redis常用命令(1)——Key
DEL 格式:DEL key [key ...] 作用:删除一个或多个 key.不存在的 key 会被忽略. 返回值:被删除 key 的数量. 示例: 192.168.1.100:6379> s ...
- python机器学习使用PCA降维识别手写数字
PCA降维识别手写数字 关注公众号"轻松学编程"了解更多. PCA 用于数据降维,减少运算时间,避免过拟合. PCA(n_components=150,whiten=True) n ...
- Hash 算法与 Manacher 算法
目录 前言 简单介绍 简述 Hash 冲突 离散化 基本结构 普通 Hash 简述 例题 字符串 Hash 简单介绍 核心思想 基本运算 二维字符串 Hash 例题 兔子与兔子 回文子串的最大长度 后 ...
- python开发--python函数-(持续更新)
1. 打印 : print() # 打印,输出 2. 变量 : var = 'hello' # 变量var , 把'hello' 赋值给变量 var 3. if 函数 : # 代码块 4个空格或者一个 ...
- 动态链接的PLT与GOT
本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/147 最近在研究缓冲区溢出攻击的试验,发现其中有一种方法叫做re ...
- 最全总结 | 聊聊 Python 办公自动化之 Excel(下)
1. 前言 前面谈到 Python 处理 Excel 文件最常见的两种方式,即:xlrd/xlwt.openpyxl 其中, xlrd/xlwt 这一组合,xlrd 可以负责读取数据,而 xlwt ...
- Java 最佳命名规则记录
类名:使用双驼峰规则.如 TestService 包名:命名全小写,且使用小写 如使用 web.csvdata.util 而不是 web.csvData.util 或 web.csvdata.util ...
- vi&vim 基本使用方法
vi/&vim 基本使用方法 本文介绍了vi (vim)的基本使用方法,但对于普通用户来说基本上够了!i/vim的区别简单点来说,它们都是多模式编辑器,不同的是vim 是vi的升级版本,它不仅 ...