写单点登录,不是不能把密码存到jwt么,我们过滤器解析之后,为什么可以根据jwt解析的数据,知道用户呢,并且框架是怎么根据这个jwt判断用户是登录的。再者如果伪造一个jwt,那我登录状态的用户不就不安全了么
第一个问题,你从哪个demo看到了把密码写到jwt里面去?
第二个问题,jwt的生成你可以简单的理解为原始数据以一定的规则转换成一个字符串(即你拿到的jwt),新字符串也能通过一定的规则还原到原始数据,我如果在原始数据中加入用户信息,那我是不是就知道了用户的信息了?
第三个问题,jwt的颁布就代表了这个用户已经登录,而且jwt生成时一般会指定过期时间,这也就限制了token一直有效的问题(业务上就是用户一次登录的最大活动时间),想想jwt如果是做用户退出的话,jwt会有什么问题
第四个问题,jwt不是你想伪造就能伪造的,一般认证服务会加入私钥,如果要求很严的话,原始数据做一次转换再转jwt也是有可能的
chatgpt:
单点登录(Single Sign-On,SSO)是一种用户在一个应用程序中登录后,可以无需再次登录就能访问其他相关应用程序的机制。其中,JWT(JSON Web Token)是一种基于 JSON 的开放标准,用于在各方之间安全地传输信息。在单点登录中,JWT 被广泛用于身份验证和授权。
关于密码存储在 JWT 中的问题,实际上是不安全的。一般来说,JWT 应该只包含一些基本的用户信息和一些用于验证和保护 JWT 的元数据,如过期时间、签名等,而不应该包含敏感数据,如密码。
当用户登录成功后,应用程序会将用户信息以及相关的元数据(如过期时间、签名等)编码为 JWT 并返回给客户端,客户端在后续的请求中将该 JWT 携带在请求头中。当请求到达服务端时,服务端会验证 JWT 的合法性,并从中提取用户信息。在这个过程中,服务端并不会保存用户的密码。
服务端通常会将 JWT 的合法性验证放在过滤器中进行。过滤器在解析请求时,会提取请求头中的 JWT 并进行验证。如果验证成功,过滤器会将从 JWT 中提取到的用户信息保存在请求的上下文中,这样后续的请求处理器就能够获取到该用户的信息,从而进行相应的业务逻辑处理。
关于 JWT 的安全性,它是基于加密和签名的技术保证的。在 JWT 中,包含有用户信息的部分是经过 Base64 编码后的字符串,并不是加密过的。为了防止 JWT 被伪造,服务端在创建 JWT 时,会为其添加签名,签名的生成过程是基于服务端保存的密钥和 JWT 的头部和有效负载部分进行的。在服务端验证 JWT 时,会再次对 JWT 的头部和有效负载进行签名,并与 JWT 中的签名进行比对。只有签名相符,才能说明该 JWT 是合法的。
尽管 JWT 的签名可以保证其安全性,但如果 JWT 的密钥被泄露,或者 JWT 被伪造,则会导致服务端的安全受到威胁。因此,服务端需要采取一些措施来确保 JWT 的安全性,例如:定期更换密钥、使用 HTTPS 等。此外,服务端还可以在 JWT 中添加更多的元数据,如过期时间、IP 地址、访问次数等,以提高 JWT 的安全性。
别人伪造必须先知道你生成JWT用的密钥才能伪造。
可以参考这个博客去了解一下 JWT
https://www.zhihu.com/question/485758060/answer/2257869896
yml配置文件
jwt:
config:
key: zhiyou100
# 有效时间24*60*60*1000
ttl: 86400000
package com.lsh.util;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* @author :LiuShihao
* @date :Created in 2020/11/3 2:16 下午
* @desc :
*/
@Data
@Component
@ConfigurationProperties(prefix ="jwt.config")
public class JwtUtil {
private String key ;
private long ttl ;
/**
* 生成JWT Token
*/
public String createJWT(String id, String subject, String roles,String permission) {
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
JwtBuilder builder = Jwts.builder()
.setId(id)
.setSubject(subject)
.setIssuedAt(now)
.signWith(SignatureAlgorithm.HS256, key)
.claim("roles", roles)
.claim("permission",permission);
if (ttl > 0) {
builder.setExpiration( new Date( nowMillis + ttl));
}
return builder.compact();
}
/**
* 解析JWT
*/
public Claims parseJWT(String jwtStr){
return Jwts.parser()
.setSigningKey(key)
.parseClaimsJws(jwtStr)
.getBody();
}
}
Token过期报错: