前端部分
需要將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跨域驗證。