内容简介:放假之前做了几个小项目+课设,都用到了token实现登录验证和权限判断,然鹅当时和同组的小伙伴也都是第一次接触到了token,于是乎都是一脸懵逼(xjbx)的写完了登录验证的前后端逻辑(我写前端,同组的小伙伴写后端)。今天有空仔细学习了一下SpringBoot实现token认证以及和前端的交互,踩了不少坑,在这里记录一下至此,工具类就编写完成啦!现在服务端给客户端签发token的功能已经差不多实现了。 那么客户端如何将token应用到以后的请求中,服务端又如何识别token呢?
放假之前做了几个小项目+课设,都用到了token实现登录验证和权限判断,然鹅当时和同组的小伙伴也都是第一次接触到了token,于是乎都是一脸懵逼(xjbx)的写完了登录验证的前后端逻辑(我写前端,同组的小伙伴写后端)。今天有空仔细学习了一下SpringBoot实现token认证以及和前端的交互,踩了不少坑,在这里记录一下
后端实现
- 首先需要导入jwt的包,相关的pom.xml文件如下:
<dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.5.0</version> </dependency> 复制代码
- 然后开始编写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<String, Object> 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<String, Object> login(@RequestBody SysUser sysUser){ Map<String, Object> 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<String> 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) } ) 复制代码
以上所述就是小编给大家介绍的《实现基于JWT的Token登录验证功能》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Django实现小程序的登录验证功能,并维护登录态
- Vue中的验证登录状态
- iOS 登录时验证手机号和倒计时发送验证码问题
- django与小程序实现登录验证功能
- Spring Security实现短信验证码登录
- springboot + shiro 验证码与记住登录
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
人人都在晒,凭什么你出彩
【美】奥斯丁•克莱恩 / 张舜芬、徐立妍 / 北京联合出版公司 / 2015-4 / 38.00
1. 《纽约时报》、亚马逊畅销书排名第1位、好评如潮的创意营销书。《出版人周刊》称其在社交网络时代“在安全范围内提供了实用的自我营销策略”。 2. TED演讲者创意分享:晒对了,全世界都为你点赞:别人在朋友圈、微博晒自拍、晒孩子、晒吃喝,你来晒创意、晒灵感、晒工作、晒收获,发出自己的声音,找到伙伴,机会也会主动找上门! 3. 10堂创意课+手绘涂鸦,所有人都能轻松读完、迅速学会的创意小......一起来看看 《人人都在晒,凭什么你出彩》 这本书的介绍吧!
HTML 压缩/解压工具
在线压缩/解压 HTML 代码
图片转BASE64编码
在线图片转Base64编码工具