简介: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);