springboot-vue-JWT使用

vue

springboot-vue-JWT使用

后端引入依赖:

     <dependency>

<groupId>io.jsonwebtoken</groupId>

<artifactId>jjwt</artifactId>

<version>0.7.0</version>

</dependency>

JWT工具类:

package com.tangzhe.util;

import java.security.interfaces.RSAPrivateKey;

import java.security.interfaces.RSAPublicKey;

import java.util.Date;

import io.jsonwebtoken.Claims;

import io.jsonwebtoken.ExpiredJwtException;

import io.jsonwebtoken.Jwts;

import io.jsonwebtoken.SignatureAlgorithm;

import io.jsonwebtoken.SignatureException;

/**

* API调用认证工具类,采用RSA加密

*/

public class JWTUtils {

private static RSAPrivateKey priKey;

private static RSAPublicKey pubKey;

private static class SingletonHolder {

private static final JWTUtils INSTANCE = new JWTUtils();

}

public synchronized static JWTUtils getInstance(String modulus, String privateExponent, String publicExponent) {

if (priKey == null && pubKey == null) {

priKey = RSAUtils.getPrivateKey(modulus, privateExponent);

pubKey = RSAUtils.getPublicKey(modulus, publicExponent);

}

return SingletonHolder.INSTANCE;

}

public synchronized static void reload(String modulus, String privateExponent, String publicExponent) {

priKey = RSAUtils.getPrivateKey(modulus, privateExponent);

pubKey = RSAUtils.getPublicKey(modulus, publicExponent);

}

public synchronized static JWTUtils getInstance() {

if (priKey == null && pubKey == null) {

priKey = RSAUtils.getPrivateKey(RSAUtils.modulus, RSAUtils.private_exponent);

pubKey = RSAUtils.getPublicKey(RSAUtils.modulus, RSAUtils.public_exponent);

}

return SingletonHolder.INSTANCE;

}

/**

* 获取Token

* @param uid 用户ID

* @param exp 失效时间,单位分钟

* @return

*/

public static String getToken(String uid, int exp) {

long endTime = System.currentTimeMillis() + 1000 * exp;

return Jwts.builder().setSubject(uid).setExpiration(new Date(endTime))

.signWith(SignatureAlgorithm.RS512, priKey).compact();

}

/**

* 获取Token

* @param uid 用户ID

* @return

*/

public String getToken(String uid) {

long endTime = System.currentTimeMillis() + 1000 * 60 * 1440;

return Jwts.builder().setSubject(uid).setExpiration(new Date(endTime))

.signWith(SignatureAlgorithm.RS512, priKey).compact();

}

/**

* 检查Token是否合法

* @param token

* @return JWTResult

*/

public JWTResult checkToken(String token) {

try {

Claims claims = Jwts.parser().setSigningKey(pubKey).parseClaimsJws(token).getBody();

String sub = claims.get("sub", String.class);

return new JWTResult(true, sub, "合法请求", ResponseCode.SUCCESS_CODE.getCode());

} catch (ExpiredJwtException e) {

// 在解析JWT字符串时,如果‘过期时间字段’已经早于当前时间,将会抛出ExpiredJwtException异常,说明本次请求已经失效

return new JWTResult(false, null, "token已过期", ResponseCode.TOKEN_TIMEOUT_CODE.getCode());

} catch (SignatureException e) {

// 在解析JWT字符串时,如果**不正确,将会解析失败,抛出SignatureException异常,说明该JWT字符串是伪造的

return new JWTResult(false, null, "非法请求", ResponseCode.NO_AUTH_CODE.getCode());

} catch (Exception e) {

return new JWTResult(false, null, "非法请求", ResponseCode.NO_AUTH_CODE.getCode());

}

}

public static class JWTResult {

private boolean status;

private String uid;

private String msg;

private int code;

public JWTResult() {

super();

}

public JWTResult(boolean status, String uid, String msg, int code) {

super();

this.status = status;

this.uid = uid;

this.msg = msg;

this.code = code;

}

public int getCode() {

return code;

}

public void setCode(int code) {

this.code = code;

}

public String getMsg() {

return msg;

}

public void setMsg(String msg) {

this.msg = msg;

}

public boolean isStatus() {

return status;

}

public void setStatus(boolean status) {

this.status = status;

}

public String getUid() {

return uid;

}

public void setUid(String uid) {

this.uid = uid;

}

}

}

前端页面文件:

     <!-- 登录 -->

<div>

<p>用户名:<input v-model="username" /></p>

<p>密码:<input v-model="password" /></p>

<button @click="login">登录</button>

</div>

...        

login: function() {
axios.post('http://localhost:8889/user/login', {
username: this.username,
password: this.password,
})
.then(function (response) {
if (response.data.status) {
alert(response.data.token);
} else {
alert("登录失败");
}
})
.catch(function (error) {
console.log(error);
});
}

后端controller:

@PostMapping("/login")

public Object login(@RequestBody LoginInfo loginInfo) {

Map<String, Object> result = new HashMap<>();

String token = userService.login(loginInfo);

if (token == null) {

result.put("status", false);

} else {

result.put("status", true);

result.put("token", token);

}

return result;

}

后端service:

public String login(LoginInfo loginInfo) {

User user = userRepository.findByUsernameAndPassword(loginInfo.getUsername(), loginInfo.getPassword());

if (user == null) {

return null;

}

String token = JWTUtils.getInstance().getToken(user.getId() + "");

return token;

}

测试登录:

登录成功返回token

token本地存储:

存储在前端

               login: function() {

axios.post('http://localhost:8889/user/login', {

username: this.username,

password: this.password,

})

.then(function (response) {

if (response.data.status) {

alert(response.data.token);

// token本地存储

localStorage.setItem("token", response.data.token);

} else {

alert("登录失败");

}

})

.catch(function (error) {

console.log(error);

});

}

// 从html本地存储中拿出token,设置到全局请求头中
axios.defaults.headers.common['Authorization'] = localStorage.getItem("token");
这样每次发送请求就能带上token的请求头了


后端解析请求头获取token,并借助jwt工具类解密出当前登录用户id:

public class LoginInfoUtils {

/**

* 获取当前登录用户id

*/

public static String getLoginUserId(HttpServletRequest request) {

String authorization = request.getHeader("Authorization");

if (StringUtils.isNotBlank(authorization)) {

JWTUtils.JWTResult result = JWTUtils.getInstance().checkToken(authorization);

if (result.isStatus()) {

return result.getUid();

}

}

return null;

}

}

后端控制台输出当前登录用户ID:

@GetMapping("/list")

public List<User> list(HttpServletRequest request) {

// 获取当前登录用户id

System.out.println("当前用户ID: " + LoginInfoUtils.getLoginUserId(request));

return userService.findAll();

}

若还没登录则输出:当前用户ID: null

用户登录则输出:当前用户ID: 6

这样,前端发送请求时,请求头中带有后端登录接口返回的token值,

后端可以从请求头中获取token并通过JWT解密获得当前登录用户id,就可以在后端获取当前登录用户了。

以上是 springboot-vue-JWT使用 的全部内容, 来源链接: utcz.com/z/376330.html

回到顶部