java jwt token 使用_实现基于JWT的Token登录验证功能

本文介绍了如何在SpringBoot中使用JWT实现登录验证和权限判断。首先引入JWT依赖,编写TokenUtil工具类,包括生成和校验Token的方法。接着在登录Controller中签发Token并返回给前端。然后创建自定义拦截器TokenInterceptor来验证每个请求的Token。最后展示了前端Vue+Axios如何封装axios,将Token放入请求头中。
摘要由CSDN通过智能技术生成

前言

放假之前做了几个小项目+课设,都用到了token实现登录验证和权限判断,然鹅当时和同组的小伙伴也都是第一次接触到了token,于是乎都是一脸懵逼(xjbx)的写完了登录验证的前后端逻辑(我写前端,同组的小伙伴写后端)。今天有空仔细学习了一下SpringBoot实现token认证以及和前端的交互,踩了不少坑,在这里记录一下

后端实现

首先需要导入jwt的包,相关的pom.xml文件如下:

com.auth0

java-jwt

3.5.0

复制代码

然后开始编写TokenUtil类,首先定义token的过期时间和私钥

private static final long EXPIRE_TIME = 15 * 60 * 1000;

private static final String TOKEN_SECRET = "thefirsttoken123";

复制代码

实现签名方法: 这里不应该使用密码进行加密,不安全,但是是自己的小demo就这样写了。

/**

* 生成签名,15分钟过期

* @param **username**

* @param **password**

* @return

*/

public static String sign(String username, String password) {

try {

// 设置过期时间

Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);

// 私钥和加密算法

Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);

// 设置头部信息

Map header = new HashMap<>(2);

header.put("Type", "Jwt");

header.put("alg", "HS256");

// 返回token字符串

return JWT.create()

.withHeader(header)

.withClaim("loginName", username)

.withClaim("pwd", password)

.withExpiresAt(date)

.sign(algorithm);

} catch (Exception e) {

e.printStackTrace();

return null;

}

}

复制代码

实现token的检验方法:

/**

* 检验token是否正确

* @param **token**

* @return

*/

public static boolean verify(String token){

try {

Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);

JWTVerifier verifier = JWT.require(algorithm).build();

DecodedJWT jwt = verifier.verify(token);

return true;

} catch (Exception e){

return false;

}

}

复制代码

至此,工具类就编写完成啦!

登录的controller层方法 这里获取到前端发送过来的请求体,取出其中的用户名和密码,和数据库比对如果无误的话,签发token,并返回给前端。 (API响应结果还没有封装,看着有点乱,嘿嘿)

@PostMapping(value = "/login")

public Map login(@RequestBody SysUser sysUser){

Map map = new HashMap<>();

String username = sysUser.getUsername();

String password = sysUser.getPassword();

if (sysUserService.login(username, password)){

String token = TokenUtil.sign(username,password);

if (token != null){

map.put("code", "10000");

map.put("message","认证成功");

map.put("token", token);

return map;

}

}

map.put("code", "00000");

map.put("message","认证失败");

return map;

}

复制代码

现在服务端给客户端签发token的功能已经差不多实现了。 那么客户端如何将token应用到以后的请求中,服务端又如何识别token呢?

实现服务端自定义拦截器

/**

* 自定义token拦截器

*/

@Component

public class TokenInterceptor implements HandlerInterceptor {

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

throws Exception {

if (request.getMethod().equals("OPTIONS")){

response.setStatus(HttpServletResponse.SC_OK);

return true;

}

response.setCharacterEncoding("utf-8");

String token = request.getHeader("admin-token");

if (token != null){

boolean result = TokenUtil.verify(token);

if(result){

System.out.println("通过拦截器");

return true;

}

}

System.out.println("认证失败");

response.getWriter().write("50000");

return false;

}

}

复制代码

TokenInterceptor实现了HandlerInterceptor接口,重写了preHandle方法,该方法是在每个请求之前触发执行,从request的头里面取出token,这里我们统一了存放token的键为admin-token,验证通过,放行,验证不通过,返回认证失败信息。 这里有一个坑,由于使用axios,每次前端发送请求,都会先发一次预请求,也就是RequestMethod为OPTIONS不是我们常见的get、post等(关于OPTIONS的解释,可以谷歌一下)。所有在这里我们需要做一次判断,如果请求方法为OPTIONS,就直接return通过。

配置拦截器 对登录界面的请求不拦截

@Configuration

public class InterceptorConfig extends WebMvcConfigurerAdapter {

private TokenInterceptor tokenInterceptor;

public InterceptorConfig(TokenInterceptor tokenInterceptor) {

this.tokenInterceptor = tokenInterceptor;

}

@Override

public void addInterceptors(InterceptorRegistry registry) {

List excludePath = new ArrayList<>();

String sysUserLogin = "/api/sysUser/login";

excludePath.add(sysUserLogin);

registry.addInterceptor(tokenInterceptor).excludePathPatterns(excludePath);

}

}

复制代码

服务端解析token 现在为了之后根据token去做相关的查询,我们需要对token进行解密,取出之前加密的loginName。然后就可以愉快的增删查改啦~

/**

* 从token中获取username信息

* @param **token**

* @return

*/

public static String getUserName(String token){

try {

DecodedJWT jwt = JWT.decode(token);

return jwt.getClaim("loginName").asString();

} catch (JWTDecodeException e){

e.printStackTrace();

return null;

}

}

复制代码

前端实现

前端使用vue+axios,主要是实现对axios的再封装。 相关代码如下 大致逻辑就是,如果vuex中已经存在了token,那么就把它放到请求头中发往服务端。

// 创建axios实例

const service = axios.create({

baseURL: process.env.BASE_API // api 的 base_url

})

// request拦截器

service.interceptors.request.use(

config => {

if (store.getters.token) {

config.headers['admin-token'] = getToken() // 让每个请求携带自定义token

}

return config

},

error => {

// 出错

console.log(error)

Promise.reject(error)

}

)

复制代码

结语

哇在掘金的第一篇文章写完了,嘻嘻,继续努力!!!。

昨日今日明日日日码不停蹄,

去年今年明年年年都是单身。

横批:这就是命

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值