网站开发总结标题,太原网站优化步骤,小程序开发团队人员架构,外网域名购买目录
#x1f397;️1.JWT介绍
#x1f39e;️2.应用场景
#x1f39f;️3.结构组成
#x1f3ab;4.JWT优点
#x1f3a0;5.封装成通用方法
#x1f6dd;6.JWT自动刷新 1.JWT介绍
官网#xff1a;JWT官网 JSON Web Token (JWT) 是一个开放标准#xff0c;它…
目录
️1.JWT介绍
️2.应用场景
️3.结构组成
4.JWT优点
5.封装成通用方法
6.JWT自动刷新 1.JWT介绍
官网JWT官网 JSON Web Token (JWT) 是一个开放标准它定义了一种用于简洁自包含的用于通信双方之间以JSON 对象的形式安全传递信息的方法。该信息可以被验证和信任因为它是数字签名的。可以使用HMAC算法或者是RSA的公钥密钥对进行签名简单来说:就是通过一定规范来生成token,然后可以通过解密算法逆向解密token,这样就可以获取用户信息 2.应用场景 Authorization (授权) : 这是使用JWT的最常见场景。一旦用户登录后续每个请求都将包含JWT允许用户访问该令牌允许的路由、服务和资源。单点登录是现在广泛使用的JWT的一个特性因为它的开销很小并且可以轻松地跨域使用。Information Exchange (信息交换) : 对于安全的在各方之间传输信息而言JSON Web Tokens无疑是一种很好的方式。因为JWT可以被签名例如用公钥/私钥对你可以确定发送人就是它们所说的那个人。另外由于签名是使用头和有效负载计算的您还可以验证内容没有被篡改。 3.结构组成 JSON Web Token由三部分组成它们之间用圆点(.)连接。这三部分分别是 (眉页)Header描述token的类型“JWT”和算法名称(有效载荷)Payload描述 加密对象的信息,如用户的id等,也可以加些规范里面的东西,如iss(签发者), exp( 过期时间)sub( 面向的用户)(签名)Signature主要是把前面两部分进行加密,防止别人拿到token进行base解密后篡改token 眉页
标头通常由两部分组成令牌类型即 JWT和正在使用的签名算法如 HMAC SHA256 或 RSA。
{alg: HS256,typ: JWT
}
然后将此 JSON 编码为 Base64Url以形成 JWT 的第一部分。
有效载荷
令牌的第二部分是有效负载其中包含声明。声明是关于实体通常为用户和其他数据的陈述。
{sub: 1234567890,name: John Doe,admin: true
}
然后对有效负载进行 Base64Url 编码以形成 JSON Web 令牌的第二部分。
签名
要创建签名部分必须获取编码的标头、编码的有效负载、机密、标头中指定的算法并对其进行签名。
HMACSHA256(base64UrlEncode(header) . base64UrlEncode(payload),secret)
签名用于验证消息在此过程中未更改并且对于使用私钥签名的令牌它还可以验证 JWT 的发送者是否是它所说的人。 4.JWT优点 简洁可通过URL,POST参数或者在HTTP header发送数据量小传输速度也很快自包含负载中包含了所有用户所需要的信息,避免了多次查询数据库;不需要在服务端保存会话信息特别适用于分布式微服务。Token是以JSON加密的形式保存在客户端所以JWT是跨语言的原则上任何web形式都支持。 5.封装成通用方法
5.1.添加依赖 !--JWT--dependencygroupIdio.jsonwebtoken/groupIdartifactIdjjwt/artifactIdversion0.7.0/version/dependency
5.2.创建工具类
/*** JWT工具包*/
Slf4j
public class JwtUtil {/*** token过期时间70天、方便测试*/private static final long EXPIRE 1000 * 60 * 60 * 24 * 7 * 70;/*** 加密的密钥*/private static final String SECRET hqdmdxz.pass;/*** 令牌前缀*/private static final String TOKEN_PREFIX hqdmdxz-PassShop;/*** 颁布者*/private static final String SUBJECT hqdmdxz;/*** 根据用户信息生成token的方法** param loginUser* return*/public static String getJsonWebToken(LoginUser loginUser) {if (loginUser null) {throw new NullPointerException(对象为空);}String token Jwts.builder().setSubject(SUBJECT)//payload.claim(head_img, loginUser.getHeadImg()).claim(id, loginUser.getId()).claim(name, loginUser.getName()).claim(mail, loginUser.getMail())//过期时间.setIssuedAt(new Date()).setExpiration(new Date(System.currentTimeMillis() EXPIRE))//加密类型.signWith(SignatureAlgorithm.HS256, SECRET).compact();token TOKEN_PREFIX token;return token;}/*** 校验token** param token* return*/public static Claims checkToken(String token) {try {final Claims claims Jwts.parser().setSigningKey(SECRET).parseClaimsJwt(token.replace(TOKEN_PREFIX, )).getBody();return claims;} catch (Exception e) {log.info(jwt,token解密失败);return null;}}
}用户登录成功后返回token即可 /*** 用户登录** param userLoginRequest* return*/Overridepublic JsonData login(UserLoginRequest userLoginRequest) {//1.根据mail匹配数据库ListUserDO mailList userMapper.selectList(new QueryWrapperUserDO().eq(mail, userLoginRequest.getMail()));//2.判断邮箱是否为空且唯一if (mailList ! null mailList.size() 1) {//已经注册//根据邮箱获取到对象UserDO userDO mailList.get(0);//根据输入的密码和查找到的盐获取加密后的密码String password Md5Crypt.md5Crypt(userLoginRequest.getPwd().getBytes(), userDO.getSecret());//判断加密后的密码是否与数据库中的一致if (password.equals(userDO.getPwd())) {//登陆成功log.info(userDO.getName() 用户登陆成功~);//TODO 生成tokenLoginUser loginUser new LoginUser();BeanUtils.copyProperties(userDO, loginUser);String token JwtUtil.getJsonWebToken(loginUser);log.info(token:{},token);return JsonData.buildSuccess(token);} else {//密码不一致return JsonData.buildResult(CodeEnum.ACCOUNT_PWD_ERROR);}} else {//未注册return JsonData.buildResult(CodeEnum.ACCOUNT_PWD_ERROR);}} 6.JWT自动刷新 在前后分离场景下,越来越多的项目使用jwt token作为接口的安全机制,但存在jwt过期后,用户无法直接感知,假如在用户操作页面期间突然提示登录则体验很不友好所以就有了token自动刷新需求~ 方案一前端控制检测token无感知刷新 用户登录成功的时候一次性给他两个Token,分别为AccessToken和RefreshTokenAccessToken有效期较短,比如1天或者5天,用于正常请求RefreshToken有效期可以设置长一些例如10天、20天作为刷新AccessToken的凭证刷新方案:当AccessToken即将过期的时候,例如提前30分钟,客户端利用RefreshToken请求指定的API获取新的AccessToken并更新本地存储中的AccessToken 核心逻辑 1、登录成功后, jwt生成AccessToken; UUID生成RefreshToken并存储在服务端redis中,设置过期时间2、接口返回3个字段AccessToken/RefreshToken/访问令牌过期时间戳3、由于RefreshToken存储在服务端redis中,假如这个RefreshToken也过期,则提示重新登录; 优点 后端压力小代码逻辑改动不大 缺点 前端每次请求需要判断token距离过期时间 方案二后端存储判断过期时间 后端存储AccessToken,每次请求过来都判断是否要过期,如果快要过期则重新生成新的token,并返回给前端重新存储,比如距离1天就过期的情况,如果用户访问对应的接口则会更新,但假如没访问则token已经过期则需要重新登录 优点 前端改动小只需要存储响应http头里面是否有新的令牌产生有的话就重新存储 缺点 后端实现复杂,且泄露后容易存在一直保活状态,且前端会存在并发请求,当并发请求收到多个jwt token时,容易生成多个token混乱使用