JWT token权限验证
概述
详细
一、前言
(1)适合人群
1,java服务端开发人员
2,初级人员开发人员
3,了解spring springboot+maven
3,了解小程序开发跟前端人员接口对接
(2) 你需要准备什么?
1,积极主动学习
2,微信开发基本流程
3,java后端几大框架掌握如(spring springboot maven mybatis)
二、前期准备工作
软件环境:idea
官方下载:https://www.eclipse.org/downloads/
1丶基本需求
1,实现token权限验证
2,项目目录结构
三、生成Token
什么是JSON Web Token?
JSON Web Token(JWT)是一个开放式标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间以JSON对象安全传输信息。这些信息可以通过数字签名进行验证和信任。可以使用秘密(使用HMAC算法)或使用RSA的公钥/私钥对对JWT进行签名。
为什么使用JWT?
随着技术的发展,分布式web应用的普及,通过session管理用户登录状态成本越来越高,因此慢慢发展成为token的方式做登录身份校验,然后通过token去取redis中的缓存的用户信息,随着之后jwt的出现,校验方式更加简单便捷化,无需通过redis缓存,而是直接根据token取出保存的用户信息,以及对token可用性校验,单点登录更为简单。
JWT的优点:
体积小,因而传输速度更快
多样化的传输方式,可以通过URL传输、POST传输、请求头Header传输(常用)
简单方便,服务端拿到jwt后无需再次查询数据库校验token可用性,也无需进行redis缓存校验
在分布式系统中,很好地解决了单点登录问题
很方便的解决了跨域授权问题,因为跨域无法共享cookie
JWT的缺点:
因为JWT是无状态的,因此服务端无法控制已经生成的Token失效,是不可控的,这一点对于是否使用jwt是需要重点考量的
获取到jwt也就拥有了登录权限,因此jwt是不可泄露的,网站最好使用https,防止中间攻击偷取jwt
在退出登录 / 修改密码时怎样实现JWT Token失效https://segmentfault.com/q/1010000010043871
对于JWT安全性:
JWT被确实存在被窃取的问题,但是如果能得到别人的token,其实也就相当于能窃取别人的密码,这其实已经不是JWT安全性的问题。网络是存在多种不安全性的,对于传统的session登录的方式,如果别人能窃取登录后的sessionID,也就能模拟登录状态,这和JWT是类似的。为了安全,https加密非常有必要,对于JWT有效时间最好设置短一点。
使用JWT部分后端代码:
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.0</version> </dependency>
Java代码:
package util; import io.jsonwebtoken.Claims; import io.jsonwebtoken.JwtBuilder; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import java.util.Date; /** * Created by Administrator on 2018/4/11. */ @ConfigurationProperties("jwt.config") public class JwtUtil { private String key ; private long ttl ;//一个小时 public String getKey() { return key; } public void setKey(String key) { this.key = key; } public long getTtl() { return ttl; } public void setTtl(long ttl) { this.ttl = ttl; } /** * 生成JWT * * @param id * @param subject * @return */ public String createJWT(String id, String subject, String roles) { long nowMillis = System.currentTimeMillis(); Date now = new Date(nowMillis); System.out.print("===="+key); System.out.print("===="+ttl); JwtBuilder builder = Jwts.builder().setId(id) .setSubject(subject) .setIssuedAt(now) .signWith(SignatureAlgorithm.HS256, key).claim("roles", roles); if (ttl > 0) { builder.setExpiration( new Date( nowMillis + ttl)); } return builder.compact(); } /** * 解析JWT * @param jwtStr * @return */ public Claims parseJWT(String jwtStr){ return Jwts.parser() .setSigningKey(key) .parseClaimsJws(jwtStr) .getBody(); } }
拦截器配置代码
package com.tensquare.user.interceptor; import io.jsonwebtoken.Claims; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import util.JwtUtil; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Created by pc-20171123 on 2019/4/3. */ @Component public class Jwtinterceptor implements HandlerInterceptor { @Autowired private JwtUtil jwtUtil; public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("经过了拦截器"); //无论如何都放行。具体能不能操作还是在具体的操作中去判断。 //拦截器只是负责把头请求头中包含token的令牌进行一个解析验证。 String header = request.getHeader("Authorization"); if(header!=null && !"".equals(header)){ //如果有包含有Authorization头信息,就对其进行解析 if(header.startsWith("Bearer ")){ //得到token String token = header.substring(7); //对令牌进行验证 try { Claims claims = jwtUtil.parseJWT(token); String roles = (String) claims.get("roles"); if(roles!=null && roles.equals("admin")){ request.setAttribute("claims_admin", token); } if(roles!=null && roles.equals("user")){ request.setAttribute("claims_user", token); } }catch (Exception e){ throw new RuntimeException("令牌不正确!"); } } } return true; } }
业务请求处理token权限验证
/** * 删除 * @param id */ public void deleteById(String id) { String token= (String) request.getAttribute("claims_admin"); if (token==null ||"".equals(token)){ throw new RuntimeException("权限不足"); } userDao.deleteById(id); }
1 ,下面来请求测试,登录
2,返回结果
3,获取令牌删除数据用postean测试,如果不填会提示权限不足
4,如果登录令牌和登录获取的令牌不一致的话提示令牌不正确
5,下面来删除数据
四、其他
暂时没