Heim >Java >javaLernprogramm >Wie integriert Spring Boot JWT, um eine Front-End- und Back-End-Authentifizierung zu erreichen?
JWT (vollständiger Name: Json Web Token) ist ein offener Standard (RFC 7519), der eine kompakte, eigenständige Möglichkeit zur sicheren Übertragung von Informationen zwischen Parteien als JSON-Objekt definiert.
Die Anmeldeinformationen jedes Benutzers werden in der Sitzung des Servers gespeichert. Mit zunehmender Anzahl von Benutzern steigt der Serveraufwand erheblich.
Sitzungsinformationen werden im Speicher des Servers gespeichert, was bei verteilten Anwendungen zu Fehlern führt. Obwohl die Sitzungsinformationen einheitlich im Redis-Cache gespeichert werden können, kann dies die Komplexität erhöhen.
Da die Sitzungsauthentifizierung auf Cookies basiert, ist sie nicht auf Nicht-Browser- und mobile Endgeräte anwendbar.
Das Front-End- und Back-End-Trennsystem, da Front-End und Back-End domänenübergreifend sind und Cookie-Informationen nicht gekreuzt werden können, sodass die Sitzungsauthentifizierung die domänenübergreifende Authentifizierung nicht fortsetzen kann.
Einfach: Das Datenvolumen des JWT-Tokens ist gering und die Übertragungsgeschwindigkeit ist ebenfalls sehr hoch.
Sprachübergreifend: JWT-Token wird auf dem Client in JSON-verschlüsselter Form gespeichert, sodass JWT sprachübergreifend ist und von jedem Webformular unterstützt wird. Plattformübergreifend: Verlässt sich nicht auf Cookies und Sitzungen und muss keine Sitzungsinformationen auf dem Server speichern. Es eignet sich sehr gut für verteilte Anwendungen und kann zur Erweiterung verwendet werden.
Der erste Teil von JWT ist der Header-Teil, bei dem es sich um ein Json-Objekt handelt, das die JWT-Metadaten beschreibt, normalerweise wie unten gezeigt.
{ "alg": "HS256", "typ": "JWT" }
Das alg-Attribut gibt den für die Signatur verwendeten Algorithmus an, der Standardwert ist HMAC SHA256 (geschrieben als HS256), das typ-Attribut gibt den Typ des Tokens an und JWT-Tokens werden einheitlich als JWT geschrieben.
Der zweite Teil von JWT ist Payload, bei dem es sich ebenfalls um ein Json-Objekt handelt. Zusätzlich zu den zu übergebenden Daten stehen sieben Standardfelder zur Auswahl. iss: Issuer exp: Ablaufzeit sub: Subject aud: User nbf: Nicht verfügbar vor iat: Release-Zeit jti: Die JWT-ID wird verwendet, um dieses JWT zu identifizieren
{ //默认字段 "sub":"主题123", //自定义字段 "name":"java", "isAdmin":"true", "loginTime":"2021-12-05 12:00:03" }
Es ist wichtig zu beachten, dass JWT standardmäßig unverschlüsselt ist, das kann jeder Entschlüsseln Sie den Inhalt. Wenn also vertrauliche Informationen hier nicht gespeichert sind, können Sie Informationslecks verhindern. Auch JSON-Objekte werden mithilfe des Base64-URL-Algorithmus in Strings umgewandelt und gespeichert.
Der Signatur-Hash-Teil besteht darin, die beiden oben genannten Datenteile zu signieren. Er muss Base64-codierte Header- und Nutzdaten verwenden und über den angegebenen Algorithmus einen Hash generieren, um sicherzustellen, dass die Daten nicht manipuliert werden.
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency>
public class JwtUtil { //创建jwt public static String createJWT(String subject, String issue, Object claim, long ttlMillis) { //当前时间 long nowMillis = System.currentTimeMillis(); //过期时间 long expireMillis = nowMillis + ttlMillis; String result = Jwts.builder() .setSubject(subject) //设置主题 .setIssuer(issue) //发行者 .setId(issue)//jwtID .setExpiration(new Date(expireMillis)) //设置过期日期 .claim("user", claim)//主题,可以包含用户信息 .signWith(getSignatureAlgorithm(), getSignedKey())//加密算法 .compressWith(CompressionCodecs.DEFLATE).compact();//对载荷进行压缩 return result; } // 解析jwt public static Jws<Claims> pareseJWT(String jwt) { Jws<Claims> claims; try { claims = Jwts.parser().setSigningKey(getSignedKey()) .parseClaimsJws(jwt); } catch (Exception ex) { claims = null; } return claims; } //获取主题信息 public static Claims getClaims(String jwt) { Claims claims; try { claims = Jwts.parser().setSigningKey(getSignedKey()) .parseClaimsJws(jwt).getBody(); } catch (Exception ex) { claims = null; } return claims; } } /** * 获取密钥 * * @return Key */ private static Key getSignedKey() { byte[] apiKeySecretBytes = DatatypeConverter .parseBase64Binary(getAuthKey()); Key signingKey = new SecretKeySpec(apiKeySecretBytes, getSignatureAlgorithm().getJcaName()); return signingKey; } private static SignatureAlgorithm getSignatureAlgorithm() { return SignatureAlgorithm.HS256; } //获取密钥,可以动态配置 public static String getAuthKey() { String auth = "123@#1234"; }
Component public class TokenInterceptor extends HandlerInterceptorAdapter { public static Log logger = LogManager.getLogger(TokenInterceptor.class); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String uri = request.getRequestURI(); logger.info("start TokenInterceptor preHandle.." + uri); //需要过滤特殊请求 if (SystemUtil.isFree(uri) || SystemUtil.isProtected(uri)) { return true; } String metohd=request.getMethod().toString(); logger.info("TokenInterceptor request method:"+metohd); //options 方法需要过滤 if("OPTIONS".equals(metohd)) { return true; } //是否开启token认证 boolean flag = SystemUtil.getVerifyToken(); ResponseResult result = new ResponseResult(); //从请求的head信息中获取token String token = request.getHeader("X-Token"); if (flag) { if(StringUtils.isEmpty(token)) { token=request.getParameter("X-Token"); } // token不存在 if (StringUtils.isEmpty(token)) { result.setCode(ResultCode.NEED_AUTH.getCode()); result.setMsg(ResultCode.NEED_AUTH.getMsg()); WebUtil.writeJson(result, response); return false; } else { Claims claims = JwtUtil.getClaims(token); String subject = ""; if (claims != null) { subject = claims.getSubject(); // 验证主题 if (StringUtils.isEmpty(subject)) { result.setCode(ResultCode.INVALID_TOKEN.getCode()); result.setMsg(ResultCode.INVALID_TOKEN.getMsg()); WebUtil.writeJson(result, response); return false; } } else { result.setCode(ResultCode.INVALID_TOKEN.getCode()); result.setMsg(ResultCode.INVALID_TOKEN.getMsg()); WebUtil.writeJson(result, response); return false; } } } return true; } }
@Configuration public class WebConfig implements WebMvcConfigurer { @Resource private TokenInterceptor tokenInterceptor; public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(tokenInterceptor).addPathPatterns("/**"); } }
@RequestMapping("login") public Result login(HttpServletResponse response) { Map<String, Object> map = new HashMap<>(); // Result result = loginAuth(user); int code = result.getCode(); //登录认证成功 if (code ==ResultCode.SUCCESS) { //默认为7天 Long ttlMillis = 7*1000 * 60 * 60 * 24; //过期时间 long expreTime = System.currentTimeMillis() + ttlMillis; String tokenKey = UUID.randomUUID().toString(); String tokenId = JwtUtil.createJWT(user.getUserId(), tokenKey, user.getPassword(), expreTime); map.put("expreTime", expreTime); map.put("tokenId", tokenId); } else { logger.error("login error:" +FastJsonUtil.toJSONString(result)); } return result; }
Das obige ist der detaillierte Inhalt vonWie integriert Spring Boot JWT, um eine Front-End- und Back-End-Authentifizierung zu erreichen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!