jwt的token如何使用呢?
JWT简介:
JWT(JSON WEB TOKEN):JSON网络令牌,JWT是一个轻便的安全跨平台传输格式,定义了一个紧凑的自包含的方式在不同实体之间安全传输信息(JSON格式)。它是在Web环境下两个实体之间传输数据的一项标准。实际上传输的就是一个字符串。广义上讲JWT是一个标准的名称;狭义上JWT指的就是用来传递的那个token字符串
JWT公司官网:
https://jwt.io/
jwt的token结构:
JWT的数据结构以及签发的过程
JWT由三部分构成:header(头部)、payload(载荷)和signature(签名)。
Header 头部信息:指定类型和算法
Payload 荷载信息:存放Claims声明信息
Signature 签名:把前两者对应的Json结构进行base64url编码之后的字符串拼接起来和密钥放一起加密后的签名
组成方式为: header.payload.signature
:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJpc3MiOiLlvKDlvLoiLCJuYW1lIjoiNzg5IiwiZXhwIjoxNTI4MzY0MjU5LCJpYXQiOjE1MjgzNjMwNTl9.574koY-c9SqMNNzfvAWQuKEnimWeZAcoFQ5XudNWF3o
因为是拼接的所以base64很容易破解,所以你不要把密码或敏感的信息放入,这样就算是被别人破解了你的荷载信息他也只能看着,
你该如何去理解JWT帮你做些什么?
结合业务场景,首先前端登录 后端通过用户名与密码验证成功后,使用jwt生成 一个具备有效期的token令牌, 这个token里面存储着 token本身的结构,加上token的过期时间,和一个你自己定义的字符串类似于加密 签名所用的盐,这个盐只有你自己知道,这样你的加密才是安全的,还可以包含一些自定义的用户信息放在荷载信息里,
jwt 如何生成Token呢?
注意:这里使用的阿里巴巴提供的json工具包,实现序列化
/** * token 工具类 * @author 郎俊楠 * */ public class JwtUtil { private static Logger logger = Logger.getLogger(JwtUtil.class); public static final String TOKEN_HEADER = "Authorization";//token的key 也是名 不要写成token这样,要按照规范来 public static final String TOKEN_PREFIX = "Bearer ";//token值的前缀,这是一种规范 ok private static final String SECRET = "mrLang";//你自己定的字符串 别让别人知道,加密时候用 盐 public static final String FUNCTS = "FUNCTS";//获取用户的功能使用的key public static final String USERINFO = "USER";//获取用户使用的key private static final long EXPIRATION = 1800L;// token的生命周期30分 /** * 创建token令牌 以下为参数都是自定义信息 * @param loginName 一般我们放用户的唯一标识登录名 * @param functs 当前用户的功能集合, 本人的rbac权限比较个性化且很负责,一般你们放role角色就可以了 * @param user 当前用户 * @return */ public static String createToken(String loginName, List<Object> functs, Users user) { Map<String, Object> map = new HashMap<>(); //当前用户拥有的功能 map.put(FUNCTS, JsonUtil.set(functs)); //当前用户信息 map.put(USERINFO, JsonUtil.set(user)); String token = Jwts.builder() .setSubject(loginName)//主题 主角是谁? 赋值登录名 .setClaims(map) .setIssuedAt(new Date())//设置发布时间,也是生成时间 .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION * 1000))//设置过期时间 .signWith(SignatureAlgorithm.HS256, SECRET)//设置HS256加密,并且把你的盐 放里,这里推荐使用SH256证书加密 .compact();//创建完成 return token; }
jwt 如何验证Token是否过期呢?
// token是否过期 public static boolean isExpiration(String token) { try { return getTokenBody(token).getExpiration().before(new Date()); } catch (Exception e) { return true; } }
jwt 如何获取自定义的信息呢?
// 获取主角,登录名 public static String getUserName(String token) { return getTokenBody(token).getSubject(); } // 获取token中存储的功能 public static List<Object> getUserFuncts(String token) { String str = getTokenBody(token).get(FUNCTS).toString(); List<Object> list = JsonUtil.getArray(str); return list; } // 获取token存储的用户 public static Object getUser(String token) { String str = getTokenBody(token).get(USERINFO).toString(); return JsonUtil.getObj(str); } // 公共获取自定义数据 public static Claims getTokenBody(String token) { return Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody(); }
jwt 如何刷新Token呢?
// 刷新token public static String refreshToken(String token) { if (isExpiration(token)) { logger.info("token刷新失败!! 过期了!!"); return null; } // 获取用户 权限信息 String functs = getTokenBody(token).get(FUNCTS).toString(); String user = getTokenBody(token).get(USERINFO).toString(); String username = getTokenBody(token).getSubject(); Map<String, Object> map = new HashMap<>(); map.put(FUNCTS, JsonUtil.set(functs)); map.put(USERINFO, JsonUtil.set(user)); token = Jwts.builder().signWith(SignatureAlgorithm.HS256, SECRET).setClaims(map).setSubject(username) .setIssuedAt(new Date()).setExpiration(new Date(System.currentTimeMillis() + EXPIRATION * 1000)) .compact(); return token; }
token 如何发送给前端?.
传入 当前用户的 功能与用户信息,登录名 生成token,写入response的返回头中,前端获取后保存在前端的本地缓存中,后续前端请求要把token放在 头header里
//登录成功之后 List<Object> functs=(List<Object>) authResult.getAuthorities();//当前功能列表 String loginName=authResult.getName();//登录名 Users obj=(Users)authResult.getPrincipal();//用户信息 String token=JwtUtil.createToken(loginName,functs,obj);//生成token //TOKEN_HEADER= Authorization TOKEN_PREFIX=Bearer token值 response.setHeader(JwtUtil.TOKEN_HEADER,JwtUtil.TOKEN_PREFIX+token); response.setContentType("application/json;charset=utf-8"); response.setStatus(HttpServletResponse.SC_OK); //个人编写的视图对象 DTO dto=new DTO<>(); dto.setCode("000000"); dto.setMessage("认证通过"); PrintWriter pw=response.getWriter(); pw.write(JsonUtil.set(dto));//写入json pw.flush();//强制刷新 pw.close();//关闭流
用户请求携带token如何验证?
你可以自定义一个过滤器,或者使用某某框架,自定义拦截器,或者aop
为了双重保险,你还需要生成一个证书 读取使用证书里面的公钥加密,私钥留着以后每次前端请求验证token的合法性就可以了
jwt提供了方法可以验证token的合法性,过期时间,还可以根据token读取用户信息,这样你把token存储前端的localstorage中,
后端的缓存都省了
这样做安全么?
你要知道 非对称加密是一套体系的,公钥私钥是一组,都存在的后端,别人不进你服务器盗取你就是安全的,要是真能登录你服务器那就直接删你库了,
罒ω罒
JWT签名算法中HS256和RS256有什么区别?
JWT签名算法中,一般有两个选择,一个采用HS256,另外一个就是采用RS256。
签名实际上是一个加密的过程,生成一段标识(也是JWT的一部分)作为接收方验证信息是否被篡改的依据。
RS256 (采用SHA-256 的 RSA 签名) 是一种非对称算法, 它使用公共/私钥对: 标识提供方采用私钥生成签名, JWT 的使用方获取公钥以验证签名。由于公钥 (与私钥相比) 不需要保护, 因此大多数标识提供方使其易于使用方获取和使用 (通常通过一个元数据URL)。
另一方面, HS256 (带有 SHA-256 的 HMAC 是一种对称算法, 双方之间仅共享一个 密钥。由于使用相同的密钥生成签名和验证签名, 因此必须注意确保密钥不被泄密。
在开发应用的时候启用JWT,使用RS256更加安全,你可以控制谁能使用什么类型的密钥。另外,如果你无法控制客户端,无法做到密钥的完全保密,RS256会是个更佳的选择,JWT的使用方只需要知道公钥。
原文地址:https://www.cnblogs.com/langjunnan/p/12464791.html
推荐阅读
-
几十年前,中国人是如何支付电费的呢?方法简单粗暴
-
身体焦虑?大码女装用实力SayNo--"书",了解更多新书拥有者数量内容 作者:小胖鸭小肥鸭 来源:趣谈神奇数字 近日,杨天真现身奇葩说,一边分享职场生存法则,一边大闹自己的大码女装品牌Plusmall。 杨天真是谁?她是壹心娱乐CEO,范冰冰、张艺兴、张雨绮等明星的前经纪人,被称为 "娱乐圈教母"。但她在2020年6月突然宣布卸下所有经纪业务,成立Plusmall,转战直播行业专心带货,第一代网红雪梨就在她的签约名单中。 在 "A4腰"、"BM风"、"筷子腿 "等流行的当下,"以瘦为美 "依然是主流审美。一向眼光犀利的杨天真,为何会选择一条看似与众不同的道路呢?其实,除了杨天真,越来越多的时尚品牌都开设了大码专线,比如耐克、H&M。 关于大码女装,你了解多少?市场潜力如何?为什么会有越来越多的参与者入局?主要形式是什么? A 超重人群居高不下,大码市场潜力数百亿美元 著名医学杂志《柳叶刀》显示,全球有 1/3 的人口超重(指 BMI 指数为 25 的人口),其中我国 4% 的超重人口(约 2.5 亿)已超过美国居世界首位。 图:超重人口比例 来源:《柳叶刀》杂志柳叶刀 国务院新闻办公室发布的《中国居民营养与慢性病状况报告(2020)》显示,我国城乡各年龄段居民超重率和肥胖率持续上升,18岁及以上居民超重率和肥胖率分别为34.3%和16.4%。
-
如何使用多个图像生成可自行移动的 gif?
-
如何使用 PHP 开发简单的账户密码生成器
-
如何判断用于嵌入式平台的 OpenCV 使用了硬件编解码器?
-
android - 如何操作应用程序的私人数据目录(删除、使用 linux 权限重新创建/恢复selinux 权限)
-
EXCEL 的 [SLOPE] 功能,你知道如何使用吗?
-
如何使用 Kotlin 连接处理 Android 中的多个 API 调用
-
如何使用 PHP 实现基于 MQTT 的客户端(代码示例)
-
对于双显卡电脑,如何判断现在使用的是独立显卡还是集成显卡?