一、Vue登录注册页面内容
<template>
<div id="login" v-loading="loading" element-loading-text="登录中...">
<el-form class="container" :model="loginForm" status-icon :rules="rules"
ref="loginForm" v-show="showLogin" label-width="100px">
<h3 class="title">MyVue 系统用户登录</h3>
<el-form-item label="用户名:" prop="username">
<el-input type="username" v-model="loginForm.username" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="密码:" prop="password">
<el-input type="password" v-model="loginForm.password" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="验证码:" prop="validCode" class="validCode">
<el-input v-model.number="loginForm.validCode"></el-input>
<el-image :src="codeUrl" @click="getValidCode" class="login-code"></el-image>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="login('loginForm')">登录</el-button>
<el-button @click="resetForm('loginForm')">重置</el-button>
<el-link type="primary" :underline="false" @click="showChange">-> 去注册</el-link>
</el-form-item>
</el-form>
<el-form class="container" :model="registerForm" status-icon :rules="rules"
ref="registerForm" v-show="!showLogin" label-width="100px">
<h3 class="title">MyVue 系统用户注册</h3>
<el-form-item label="用户名:" prop="username">
<el-input type="username" v-model="registerForm.username" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="密码:" prop="password">
<el-input type="password" v-model="registerForm.password" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="确认密码:" prop="rePassword">
<el-input type="rePassword" v-model="registerForm.rePassword" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="验证码:" prop="validCode" class="validCode">
<el-input v-model.number="registerForm.validCode"></el-input>
<el-image :src="codeUrl" @click="getValidCode" class="login-code"></el-image>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="register('registerForm')">注册</el-button>
<el-button @click="resetForm('registerForm')">重置</el-button>
<!-- #606266 #5cb6ff-->
<el-link type="primary" :underline="false" @click="showChange">-> 去登录</el-link>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
name: 'Login',
data () {
var validateChkcode = (rule, value, callback) => {
if (value === '') {
return callback(new Error('请输入验证码!'))
}
callback()
}
var validateUsername = (rule, value, callback) => {
if (value === '') {
callback(new Error('请输入用户名!'))
} else if (!this.showLogin) {
// 异步原因,不会等待返回后再执行后面流程,而是直接执行else后面的语句
this.$get('user/chkUsername', this.registerForm).then(retDate => {
if (retDate === 1) {
callback(new Error('该用户名已经存在!'))
}
callback()
})
} else {
callback()
}
}
var validatePassword = (rule, value, callback) => {
if (value === '') {
callback(new Error('请输入密码!'))
}
callback()
}
var validateRePassword = (rule, value, callback) => {
if (value === '') {
callback(new Error('请再次输入密码!'))
} else if (value !== this.registerForm.password) {
callback(new Error('两次输入密码不一致!'))
}
callback()
}
return {
showLogin: true,
loading: false,
codeUrl: '',
cookiePass: '',
loginForm: {
username: '',
password: '',
validCode: '',
id: ''
},
registerForm: {
username: '',
password: '',
rePassword: '',
validCode: '',
id: ''
},
rules: {
username: [
{ validator: validateUsername, trigger: 'blur' }
],
password: [
{ validator: validatePassword, trigger: 'blur' }
],
validCode: [
{ validator: validateChkcode, trigger: 'blur' }
],
rePassword: [
{ validator: validateRePassword, trigger: 'blur' }
]
}
}
},
created () {
this.getValidCode()
},
methods: {
showMessage (message) {
this.$message.error(message)
},
login (formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
this.loading = true
this.$post('user/login', this.loginForm).then(retDate => {
if (retDate.ok) {
this.$store.dispatch('setUser', retDate)
this.$router.push({path: '/'})
} else {
this.showMessage(retDate.message)
this.loading = false
}
})
} else {
console.log('error submit!!')
return false
}
})
},
register (formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
this.$post('user/register', this.registerForm).then(retDate => {
if (retDate.ok) {
this.$store.dispatch('setUser', retDate)
// 注册成功跳转到首页
this.$message.success(retDate.message)
this.$router.push({path: '/'})
} else {
this.showMessage(retDate.message)
}
})
} else {
console.log('error submit!!')
return false
}
})
},
resetForm (formName) {
this.$refs[formName].resetFields()
},
getValidCode () {
this.codeUrl = this.$global.baseURL + 'user/getCheckCode?' + new Date()
},
showChange () {
this.showLogin = !this.showLogin
this.getValidCode()
}
}
}
</script>
<style>
#login {
background:url("../assets/backImg.jpg") no-repeat;
background-position: center;
height: 100%;
width: 100%;
background-size: cover;
position: fixed;
}
body{
margin: 0px;
}
.container {
border-radius: 15px;
background-clip: padding-box;
margin: 8% auto;
width: 350px;
padding: 35px 35px 15px 35px;
background: #fff;
border: 1px solid #eaeaea;
box-shadow: 0 0 25px #cac6c6;
}
.title {
margin: 0px auto 40px auto;
text-align: center;
color: #505458;
}
.login-code {
display: inline-block;
height: 40px;
float: right;
}
.validCode .el-input {
float: left;
width: 50%;
}
.el-link {
margin-left: 25px;
}
img {
float: right;
}
</style>
二、后台controller文件内容:
package com.login.controller;
import com.login.util.DateUtil;
import com.login.util.Md5Util;
import com.login.util.StringUtil;
import com.login.util.VerifyCodeUtil;
import com.mydatasource.entity.User;
import com.mydatasource.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
/**
* 文件描述: 用户登录,注册
*
* @author yuzonghao
* @date 2020/05/22 14:43
**/
@RestController
public class LoginController {
private static Logger log = LoggerFactory.getLogger(LoginController.class);
@Autowired
private UserService userService;
@RequestMapping("/register")
public String register(HttpServletRequest request, @RequestBody User user){
String verifyCode = (String) request.getSession().getAttribute("verifyCode");
log.info("获取验证码的值为: {}",verifyCode);
if (!user.getValidCode().equalsIgnoreCase(verifyCode)){
user.setOk(false);
user.setMessage("验证码输入错误!");
return StringUtil.toJson(user);
}
user.setId(DateUtil.dataFormat(new Date(),DateUtil.DateTimeNum)
+ StringUtil.getRandomStr());
user.setPassword(Md5Util.encoderByMd5(user.getPassword()));
int num = userService.insertUser(user);
if (num <= 0){
user.setOk(false);
user.setMessage("注册失败!");
return StringUtil.toJson(user);
}
user.setMessage("注册成功!");
return StringUtil.toJson(user);
}
@RequestMapping("/login")
public String login(HttpServletRequest request, @RequestBody User user){
String verifyCode = (String) request.getSession().getAttribute("verifyCode");
log.info("获取验证码的值为: {}",verifyCode);
if (!user.getValidCode().equalsIgnoreCase(verifyCode)){
user.setOk(false);
user.setMessage("验证码输入错误!");
return StringUtil.toJson(user);
}
user = userService.selectUser(user.getUsername(), Md5Util.encoderByMd5(user.getPassword()));
if (user == null){
return StringUtil.toJson(new User(false,"账号或密码错误!"));
}
return StringUtil.toJson(user);
}
@GetMapping("/chkUsername")
public String chkUsername(@RequestParam String username){
if (userService.chkUsername(username)) return "1";
return "0";
}
/**
* description: 获取验证码图片
* param [response, request]
* author yuzonghao
* createTime 2020/3/7 13:36
**/
@GetMapping("/getCheckCode")
public void getCheckCode(HttpServletResponse response, HttpServletRequest request) {
try {
int width = 120;
int height = 40;
BufferedImage verifyImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//生成对应宽高的初始图片
String randomText = VerifyCodeUtil.drawRandomText(width, height, verifyImg);
request.getSession().setAttribute("verifyCode", randomText);
// request.getSession().setAttribute("startTime",new Date());
response.setContentType("image/png");//必须设置响应内容类型为图片,否则前台不识别
OutputStream os = response.getOutputStream(); //获取文件输出流
ImageIO.write(verifyImg, "png", os);//输出图片流
os.flush();
os.close();//关闭流
} catch (IOException e) {
log.error("获取验证码图片失败!", e);
}
}
}
Md5Util
package com.example.myblog.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Encoder;
import java.security.MessageDigest;
/**
* 文件描述:
*
* @author yuzonghao
* @date 2020/05/27 14:19
**/
public class Md5Util {
private static Logger log = LoggerFactory.getLogger(Md5Util.class);
public static String encoderByMd5(String str) {
if (str == null) return null;
try {
//确定计算方法
MessageDigest md5 = MessageDigest.getInstance("MD5");
BASE64Encoder base64en = new BASE64Encoder();
//加密后的字符串
return base64en.encode(md5.digest(str.trim().getBytes("utf-8")));
} catch (Exception e) {
log.error("字符串Md5加密失败,",e);
}
return null;
}
}
VerifyCodeUtil
package com.example.myblog.util;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;
/**
* @description: 生成验证码工具类
* @projectName:personal
* @author:yuzonghao
* @createTime:2020/3/7 12:57
*/
public class VerifyCodeUtil {
private static String baseNumLetter = "123456789abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
private static String font = "微软雅黑";
/**
* description: 绘制验证码图片,返回验证码文本内容
* param [width, height, verifyImg]
* author yuzonghao
* createTime 2020/3/7 13:06
**/
public static String drawRandomText(int width, int height, BufferedImage verifyImg) {
Graphics2D graphics = (Graphics2D) verifyImg.getGraphics();
graphics.setColor(Color.WHITE);//设置画笔颜色-验证码背景色
graphics.fillRect(0, 0, width, height);//填充背景
graphics.setFont(new Font(font, Font.BOLD, 30));
StringBuffer sBuffer = new StringBuffer();
int x = 10; //旋转原点的 x 坐标
String ch = "";
Random random = new Random();
for(int i = 0;i < 4;i++){
graphics.setColor(getRandomColor());
//设置字体旋转角度
int degree = random.nextInt() % 10; //角度小于10度
int dot = random.nextInt(baseNumLetter.length());
ch = baseNumLetter.charAt(dot) + "";
sBuffer.append(ch);
//正向旋转
graphics.rotate(degree * Math.PI / 180, x, 30);
graphics.drawString(ch, x, 30);
//反向旋转
graphics.rotate(-degree * Math.PI / 180, x, 30);
x += 25;
}
//画干扰线
for (int i = 0; i <15; i++) {
// 设置随机颜色
graphics.setColor(getRandomColor());
// 随机画线
graphics.drawLine(random.nextInt(width), random.nextInt(height),
random.nextInt(width), random.nextInt(height));
}
//添加噪点
for(int i=0;i<15;i++){
int x1 = random.nextInt(width);
int y1 = random.nextInt(height);
graphics.setColor(getRandomColor());
graphics.fillRect(x1, y1, 2,2);
}
return sBuffer.toString();
}
/**
* description: 获取随机颜色
* param []
* author yuzonghao
* createTime 2020/3/7 12:55
**/
private static Color getRandomColor(){
Random ran = new Random();
Color color = new Color(ran.nextInt(256),
ran.nextInt(256),ran.nextInt(256));
return color;
}
}
三、效果图: