Spring Boot + JWT + Vue
实现功能
前端登录成功后 后端给前端一个token 之后前端带着这个token去进行操作并让后端检验
后端搭建
编写实体类
package com.jie.bootjwt.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String username;
private String password;
private String token;
}
编写工具类 生成token
package com.jie.bootjwt.util;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import java.util.UUID;
public class JwtUtil {
private static long time=1000*60*60*24;
private static String signature="admin";
public static String CreateToken(){
JwtBuilder jwtBuilder= Jwts.builder();
String jwtToken=jwtBuilder
.setHeaderParam("typ","JWT")
.setHeaderParam("alg","HS256")
.claim("username","tom")
.setSubject("admin")
.setExpiration(new Date(System.currentTimeMillis()+time))
.setId(UUID.randomUUID().toString())
.signWith(SignatureAlgorithm.HS256,signature)
.compact();
return jwtToken;
}
}
编写控制类 这里就不连数据库了
package com.jie.bootjwt.controller;
import com.jie.bootjwt.pojo.User;
import com.jie.bootjwt.util.JwtUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
private final String USERNAME="root";
private final String PASSWORD="123456";
@GetMapping("/login")
public User login(User user){
if(user.getUsername().equals(USERNAME) && user.getPassword().equals(PASSWORD)){
//登录成功 添加token
user.setToken(JwtUtil.CreateToken());
return user;
}
return null;
}
}
控制类添加@CrossOrigin注解解决垮域问题
前端编写
输入vue create jwt-demo创建项目
安装ele
npm install element-ui -S
main.js中引入ele
import Element from "element-ui";
import "element-ui/lib/theme-chalk/index.css";
Vue.use(Element);
安装axios
vue add axios
编写一个简单的登录页面
<template>
<div>
<el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
<el-form-item label="用户名" prop="username">
<el-input v-model="ruleForm.username"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input type="password" v-model="ruleForm.password" autocomplete="off"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data() {
return {
ruleForm: {
username: '',
password: '',
},
rules: {
password: [
{ require:true,message:'请输入密码', trigger: 'blur' }
],
username: [
{ require:true,message:'请输入用户名', trigger: 'blur'}
]
}
};
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
let _this=this
axios.get('http://localhost:8181/login',{params:_this.ruleForm}).then(
function (resp){
console.log(resp.data)
}
)
} else {
console.log('error submit!!');
return false;
}
});
},
}
}
</script>
<style scoped>
</style>
使用axios提交数据给后端 并获取后端返回的数据
if (valid) {
let _this=this
axios.get('http://localhost:8181/login',{params:_this.ruleForm}).then(
function (resp){
console.log(resp.data)
}
)
}
测试发现成功获得

实现token的检验
首先在登录成功后 我们吧token保存到本地数据里面 之后所有操作都会去检查这个token
if (valid) {
let _this=this
axios.get('http://localhost:8181/login',{params:_this.ruleForm}).then(
function (resp){
if(resp.data!=null){//成功获取
//将JSON转化成字符串格式 保存在localStorage中
localStorage.setItem("access-admin",JSON.stringify(resp.data))
//跳转到登录页面
_this.$router.replace({path:'/'})
}
}
)
}
写两个网页可以互相跳转 模拟平时上网的操作
home.vue
<template>
<div class="home">
欢迎 {{admin.username}}
<div id="nav">
<router-link to="/about">下载</router-link>
</div>
<h1>这是首页</h1>
</div>
</template>
<script>
// @ is an alias to /src
export default {
data(){
return {
admin:''
}
},
created() {
this.admin=JSON.parse(window.localStorage.getItem('access-admin'))
}
}
</script>
about.vue
<template>
<div class="about">
欢迎 {{admin.username}}
<div id="nav">
<router-link to="/">首页</router-link>
</div>
<a href="">资源1</a> |
<a href="">资源2</a> |
<a href="">资源3</a> |
<a href="">资源4</a> |
<a href="">资源5</a> |
</div>
</template>
<script>
export default {
data(){
return {
admin:''
}
},
created() {
this.admin=JSON.parse(window.localStorage.getItem('access-admin'))
}
}
</script>
配置路由规则
由于要实现在任何跳转上vue的路由上进行设置
index.js代码
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import Login from "@/views/Login";
import Error from "@/views/Error";
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/login',
name: 'Login',
component: Login
},
{
path: '/error',
name: 'Error',
component: Error
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]
const router = new VueRouter({
routes
})
//路由设置
router.beforeEach((to,from,next)=>{
if(to.path.startsWith('/login')){
//如果访问的是登录页面 就删除旧的token
window.localStorage.removeItem('access-admin')
next()
}
else {
//尝试获取token
let admin=JSON.parse(window.localStorage.getItem('access-admin'))
//如果没有token就直接跳转到登录页面
if(!admin){
next({path:'/login'})
}
else {
//检查token是否正确
axios({
url:'http://localhost:8181/checkToken',
method:'get',
//将信息保存在header里
headers:{
token:admin.token
}
}).then((response)=>{
if(!response.data){
console.log('检验失败')
next({path:'/error'})
}
})
next()
}
}
})
export default router
编写一个error组件用于提醒token失效同时跳转
<template>
</template>
<script>
export default {
name: "Error",
created() {
let _this=this
this.$alert('登录信息失效','提示',{
confirmButtonText:'确定'
}).then((response)=>{
localStorage.removeItem('access-admin')
_this.$router.replace({path:'/login'})
})
}
}
</script>
<style scoped>
</style>
后端实现检查token功能
工具类添加检查方法
public static boolean CheckToken(String token){
if(token==null) return false;
JwtParser jwtParser=Jwts.parser();
//进行解密
try{
Jws<Claims> claimsJws = jwtParser.setSigningKey(signature).parseClaimsJws(token);
}
catch (Exception e){
//出现异常即说明token失效或者其他问题
return false;
}
return true;
}
控制类调用该方法即可
@GetMapping("/checkToken")
public Boolean checkToken(HttpServletRequest request){
String token = request.getHeader("token");
return JwtUtil.CheckToken(token);
}
为了方便测试 我们吧token的生存时间效果到6秒

测试在点击网页过了6秒后就会提示信息失效


浙公网安备 33010602011771号