当用户不需要输入账号密码直接通过网址到后台的话,那么是十分危险的。所以才有了登录拦截的思想,但凡没有登录过的就需要拦截下来。JWT又称Json Web Token。具体思路就是:
1、服务器生成一个Json格式的Token给客服端保存到浏览器当中,这里我采用的是localStorage当地存储而不是sessionStorage会话存储。这里的区别就是sessionStorage是当浏览器关闭就会删除其存储的token。
2、当每次访问一个页面(也可以说是调用前端接口方法)时就会向服务器传回去token进行校验,如果不是刚开始存储的token又或者是过期的token,那么我直接返回到登录页面。
3、服务器再对这个token进行校验,通过返回true,失败返回false。
具体代码如下:
前端:
<script>
export defalue{
data(){
return{
loginForm:{
username:"",
password:"",
verify:""
}
}
},
methods:{
//点击登录的时候执行这个方法
handleLogin() {
//注意这里的路径要配合后端的Controller
axios.post('http://localhost:8080/userlogin/user',this.loginForm).then((resp)=>{
if(this.loginForm.username == "" || this.loginForm.password == "") {
this.$alert("用户名或密码不能为空")
}else if(this.loginForm.verify == ""){
this.$alert("验证码不能为空")
}else {
if(resp.data != null){
this.$message({
showClose: true,
message: '登录成功',
type: 'success'
});
//主要在乎的我这篇文章所需要的当地存储
//access-admin表示key,服务器传过来的表示value
localStorage.setItem('access-admin',JSON.stringify(resp.data))
this.$router.push('/index')
}else {
this.$alert("用户名或密码或验证码错误")
}
}
})
}
}
</script>
<!--router/index.js即路由下配置前端拦截器-->
import Axios from 'axios'
import VueRouter from 'vue-router'
VueRouter.beforeEach((to,from,next) => {
if(to.path === "/"){
window.localStorage.removeItem('access-admin')
next()
}else{
let admin = JSON.parse(window.localStorage.getItem('access-admin'))
if(!admin){
next("/")
}else{
//校验token合法性
Axios({
url:'http://localhost:8080/userlogin/checkToken',
method:'get',
headers:{
token:admin
}
}).then((resp) => {
if(!resp.data){
next("/")
}
})
next()
}
}
})
//获取原型对象上的push函数
const originalPush = VueRouter.prototype.push
//修改原型对象中的push方法
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
后端:
package com.chf.util;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.stereotype.Component;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
//先准备一个关于Json Web Token的工具类
@Component
public class JWTUtil {
//token私钥
static Algorithm algorithm = Algorithm.HMAC256("f26e587c28064d0c855c72c0a6a0e618");
/**
* 生成token
* @param username
* @param password
* @return
*/
public static String createToken(String username,String password){
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND,15 * 60);
Map<String,Object> header = new HashMap<>();
header.put("typ", "JWT");
header.put("alg", "HS256");
return JWT.create()
.withHeader(header)
.withClaim("username",username)
.withClaim("password",password)
.withExpiresAt(calendar.getTime())
.sign(algorithm);//签名密钥算法
}
/**
* 校验token
* @param token
* @return
*/
public static boolean verify(String token){
if(token == null){
return false;
}
try{
JWTVerifier jwtVerifier = JWT.require(algorithm).build();
jwtVerifier.verify(token);
return true;
}catch (Exception e){
e.printStackTrace();
return false;
}
}
}
@RestController
@RequestMapping("/userlogin")
public class LoginController {
@GetMapping("/checkToken")
public Boolean checkToken(HttpServletRequest request){
String token = request.getHeader("token");
return JWTUtil.verify(token);
}
}