簡介:JWT是一種用於雙方之間傳遞安全信息的簡潔的、URL安全的表述性聲明規範。JWT做爲一個開放的標準( RFC 7519 ),定義了一種簡潔的,自包含的方法用於通訊雙方之間以Json對象的形式安全的傳遞信息。由於數字簽名的存在,這些信息是可信的,JWT可使用HMAC算法或者是RSA的公私祕鑰對進行簽名。html
簡潔(Compact): 能夠經過URL,POST參數或者在HTTP header發送,由於數據量小,傳輸速度也很快java
自包含(Self-contained):負載中包含了全部用戶所須要的信息,避免了屢次查詢數據庫web
原理性的東西能夠參考 http://www.jianshu.com/p/576dbf44b2ae 這裏只介紹在jeesite項目中怎麼使用.算法
(1).首先引入jwt依賴jar包spring
<!--jjwt--> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.7.0</version> </dependency>
(2).建立JwtUtil類,包括建立jwt方法和解析jwt方法數據庫
import com.weichai.common.mapper.JsonMapper; import com.weichai.modules.rest.config.Constant; import com.weichai.modules.rest.entity.AppUser; import io.jsonwebtoken.Claims; import io.jsonwebtoken.JwtBuilder; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.apache.commons.codec.binary.Base64; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.util.Date; @Component public class JwtUtil { @Value("${spring.profiles.active}") private String profiles; /** * 由字符串生成加密key * @return */ public SecretKey generalKey(){ String stringKey = profiles+ Constant.JWT_SECRET; byte[] encodedKey = Base64.decodeBase64(stringKey); SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES"); return key; } /** * 建立jwt * @param id * @param subject * @param ttlMillis * @return * @throws Exception */ public String createJWT(String id, String subject, long ttlMillis) throws Exception { SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; long nowMillis = System.currentTimeMillis(); Date now = new Date(nowMillis); SecretKey key = generalKey(); JwtBuilder builder = Jwts.builder() .setId(id) .setIssuedAt(now) .setSubject(subject) .signWith(signatureAlgorithm, key); if (ttlMillis >= 0) { long expMillis = nowMillis + ttlMillis; Date exp = new Date(expMillis); builder.setExpiration(exp); } return builder.compact(); } /** * 解密jwt * @param jwt * @return * @throws Exception */ public Claims parseJWT(String jwt) throws Exception { SecretKey key = generalKey(); Claims claims = Jwts.parser() .setSigningKey(key) .parseClaimsJws(jwt).getBody(); return claims; } /** * 生成subject信息 * @param appUser * @return */ public static String generalSubject(AppUser appUser){ return JsonMapper.toJsonString(appUser); } }
(3)登陸成功後將用戶信息放入jwt中,生成後返回給app端apache
String subject = JwtUtil.generalSubject(appUser);--將用戶信息轉換成json格式 String token = jwt.createJWT(Constant.JWT_ID, subject, Constant.JWT_TTL); ret.put("userInfo",appUser); ret.put("userToken", token);
(4)app端登錄成功頁面每次請求都會在header中帶着jwt信息,請求數據(ionic2中請求方式)json
public httpPostWithAuth(url: string, body: any) {
let userToken = this.storageService.read<string>('userToken');
//alert(userToken);
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Authorization', userToken);
let options = new RequestOptions({ headers: headers });
return this.http.post(url, body, options).toPromise().then(res => res.json())
.catch(err => {
this.handleError(err);
});
}
(5)服務端獲取header中jwt,進行解析,若是jwt過時則返回錯誤碼提示用戶從新登陸;若是jwt解密正常,則能夠得到用戶信息,根據狀況進行操做,最後再次刷新token,將最新token返回給app端。安全
String userToken = request.getHeader("Authorization"); if(userToken==null || "".equals(userToken)){ return new ApiReponseData.Builder("401").message("用戶未受權").build(); } AppUser au = new AppUser(); try { //根據userToken 獲取用戶信息 Claims claims = jwt.parseJWT(userToken); au = (AppUser) JsonMapper.fromJsonString(claims.getSubject(), AppUser.class);--解密jwt獲得用戶信息 }catch(Exception e){ e.printStackTrace(); return new ApiReponseData.Builder("401").message("用戶未受權").build(); }
String subject = JwtUtil.generalSubject(au);--獲取最新用戶信息生成最新jwt,傳回app端 String token = jwt.createJWT(Constant.JWT_ID, subject, Constant.JWT_TTL); j.put("userToken",token);