JWT (nama penuh: Json Web Token) ialah standard terbuka (RFC 7519) yang mentakrifkan cara yang ringkas dan serba lengkap untuk berkomunikasi antara pihak sebagai objek JSON dengan selamat antara
Maklumat log masuk setiap pengguna akan disimpan dalam Sesi pelayan Apabila bilangan pengguna bertambah, overhed pelayan akan meningkat dengan ketara.
Maklumat sesi disimpan dalam memori pelayan, yang boleh menyebabkan kegagalan untuk aplikasi yang diedarkan Walaupun maklumat sesi boleh disimpan secara seragam dalam cache Redis, ini boleh meningkatkan kerumitan seks.
Memandangkan pengesahan Sesi adalah berdasarkan Kuki, ia tidak terpakai kepada terminal bukan penyemak imbas dan mudah alih.
Sistem pemisahan bahagian hadapan dan bahagian belakang, kerana bahagian hadapan dan bahagian belakang ialah domain silang dan maklumat kuki tidak boleh dipalang, jadi pengesahan sesi tidak boleh diteruskan silang -pengesahan domain.
Mudah: Jumlah data JWT Token adalah kecil dan kelajuan penghantaran adalah pantas.
Merentas bahasa: Token JWT disimpan pada klien dalam bentuk yang disulitkan JSON, jadi JWT ialah bahasa silang dan disokong oleh mana-mana borang web. Cross-platform: tidak bergantung pada kuki dan sesi, dan tidak perlu menyimpan maklumat sesi pada pelayan Ia sangat sesuai untuk aplikasi yang diedarkan dan boleh digunakan untuk pengembangan.
Bahagian pertama JWT ialah bahagian pengepala, iaitu perihalan JWT A Json objek metadata, biasanya seperti yang ditunjukkan di bawah.
{ "alg": "HS256", "typ": "JWT" }
Atribut alg menunjukkan algoritma yang digunakan untuk tandatangan lalai ialah HMAC SHA256 (ditulis sebagai HS256 Atribut taip menunjukkan jenis token JWT secara seragam.
Bahagian kedua JWT ialah Payload, yang juga merupakan objek Json Selain mengandungi data yang perlu dihantar, terdapat tujuh medan lalai untuk dipilih. iss: penerbit exp: masa tamat sub: topik aud: pengguna nbf: tidak tersedia sebelum iat: masa penerbitan jti: JWT ID digunakan untuk mengenal pasti JWT ini
{ //默认字段 "sub":"主题123", //自定义字段 "name":"java", "isAdmin":"true", "loginTime":"2021-12-05 12:00:03" }
Perlu diingat bahawa secara lalai JWT tidak disulitkan dan sesiapa sahaja boleh mentafsir kandungannya, jadi jika anda mempunyai beberapa maklumat sensitif, jangan simpannya di sini untuk mengelakkan kebocoran maklumat. Objek JSON juga ditukar kepada rentetan menggunakan algoritma URL Base64 dan disimpan.
Bahagian cincang tandatangan adalah untuk menandatangani dua bahagian data di atas Ia perlu menggunakan pengepala dan data muatan yang dikodkan base64 dan menjana cincang melalui algoritma yang ditentukan untuk memastikan bahawa. data tidak akan diusik.
<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; }
Atas ialah kandungan terperinci Bagaimanakah Spring Boot mengintegrasikan JWT untuk mencapai pengesahan bahagian hadapan dan belakang?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!