JWT - 通过Axios拦截器完成Token转发实现单点登录
程序员文章站
2024-03-19 15:24:28
...
前端部分
需要将token字符串
和用户信息
存入的Cookie中,因此需要引入js-cookie
。前端采用axios
发送请求,所以还需要引入axios
。
1、封装axios
创建一个request.js
文件,用来封装axios
。
import axios from 'axios'; // 引入axios
import cookie from 'js-cookie'; // 引入js-cookie
// 创建axios实例
const service = axios.create({
baseURL:'http://localhost:9000', // 请求地址,可以使用nginx代理
timeout:20000 // 请求超时时间
});
// 配置request拦截器
service.interceptors.request.use(
config => {
// 如果Cookie中存在这个token,就在header中设置这个token
// 这样token就可以跨域转发
if(cookie.get('user_token')){
config.headers['token'] = cookie.get('user_token');
}
return config;
},
err => { // 出错调用
return Promise.reject(err);
}
)
export default service;
2、定制API - login.js
定制登录
的方法。
import request from '@/utils/request'; // 引入request.js
export default {
/**
* 登录的方法
* @param userInfo 用户登录信息
*/
submitLogin(userInfo){
return request({
// 登录的请求地址,完整即http://localhost:9000/user/login
url:'/user/login',
method:'post', // 请求方式
data:userInfo // 请求信息
});
}
}
3、完成登录 - 基于Vue和Axios发送请求
import cookie from 'js-cookie'
import loginApi from '@/api/login'
export default{
data(){
return {
user:{
mobile:'', // 手机/账号
password:'', // 密码
},
loginInfo:{}, // 登录用户信息
}
},
methods:{
/**
* 登录按钮调用的方法
*/
submitLogin(){
/**
* 调用登录API
*/
loginApi.submitLogin(this.user)
.then(response => {
// 将服务端传过来的token字符串存入cookie
cookie.set('user_token',response.data.data.token,{domain:'localhsot'});
// 这里就可以调用方法去获取用户信息并存入Cookie了
// 方法就不再定义了,直接使用,定义方式与前面一致
// 因为在request.js中制定了拦截器,会检查token是否存在,存在就跟着header信息一起被传走
loginApi.getLoginUserInfo()
.then(response => {
this.loginInfo = response.data.data.userInfo;
// 将获取到的用户信息存入到cookie中,其他页面从cookie中取
cookie.set('user_info',this.loginInfo,{domain:'localhost'});
// 跳转到首页 - 也可以使用路由跳转
// 首页就可以从cookie中获取了
window.location.href = "/";
})
})
}
}
}
4、登录成功,信息获取
在cookie中获取信息,通过JSON.parse
方法将其转换为JSON对象。
后端部分
1、要使用JWT,需要引入JWT的依赖
<!-- JWT-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
2、创建JWT帮助类
public class JwtUtils {
// 常量
public static final long EXPIRE = 1000 * 60 * 60 * 24; // token过期时间
public static final String APP_SECRET = "ukc8BDbRigUDaY6pZFfWus2jZWLPHO"; // 秘钥
// 生成token字符串的方法
public static String getJwtToken(String id, String nickname){
String JwtToken = Jwts.builder()
// 头信息
.setHeaderParam("typ", "JWT")
.setHeaderParam("alg", "HS256")
.setSubject("guli-user") // 分类
// 设置过期时间
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + EXPIRE))
// 设置Token主体部分,存储用户信息
.claim("id", id)
.claim("nickname", nickname)
.signWith(SignatureAlgorithm.HS256, APP_SECRET)
.compact();
return JwtToken;
}
/**
* 判断token是否存在与有效
* @param jwtToken
* @return
*/
public static boolean checkToken(String jwtToken) {
if(StringUtils.isEmpty(jwtToken)) return false;
try {
Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 判断token是否存在与有效
* @param request
* @return
*/
public static boolean checkToken(HttpServletRequest request) {
try {
String jwtToken = request.getHeader("token");
if(StringUtils.isEmpty(jwtToken)) return false;
Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 根据token字符串获取id
*/
public static String getMemberIdByJwtToken(HttpServletRequest request) {
String jwtToken = request.getHeader("token");
if(StringUtils.isEmpty(jwtToken)) return "";
Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
Claims claims = claimsJws.getBody();
return (String)claims.get("id");
}
}
3、验证用户登录成功之后生成Token字符串
String jwtToken = JwtUtils.getJwtToken(user.getId(),user.getNickname());
4、根据token信息获取用户信息
前面前端部分说了,每次请求的时候,都会将token信息放入header,这样就可以跨域(cookie无法跨域)。
要获取用户信息,则需要通过这个token信息来确定,使用jwt帮助类中的getMemberIdByJwtToken
方法来获取。
/**
* 根据token字符串获取id
*/
public static String getMemberIdByJwtToken(HttpServletRequest request) {
String jwtToken = request.getHeader("token");
if(StringUtils.isEmpty(jwtToken)) return "";
Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
Claims claims = claimsJws.getBody();
return (String)claims.get("id");
}
获取到id,我们就可以通过这个id去获取用户信息。
@GetMapping("/getUserInfo")
public R getMemberInfo(HttpServletRequest request){
String userId = JwtUtils.getMemberIdByJwtToken(request);
User user= userService.getById(userId);
return R.ok().data("userInfo",user);
}
到此为止,完成了一个简单的token跨域验证。
上一篇: 查找算法之二分法查找
下一篇: 实习笔记(一)