補充知識點五:基於Token的WEB後臺認證機制
阿新 • • 發佈:2018-12-25
自己寫的例項:
1.引入JAR包
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId >
<artifactId>fastjson</artifactId>
<version>1.2.28</version>
</dependency>
2.生成token,校驗token
package org.pc;
import com.alibaba.fastjson.JSONObject;
import io.jsonwebtoken.*;
import io.jsonwebtoken.impl.Base64Codec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
/**
* @author **
* @date 2018/6/8 8:47
* Token認證:
* JWT 標準的 Token 有三個部分:
* 1.header(頭部),頭部資訊主要包括(引數的型別--JWT,簽名的演算法--HS256)
* 2.payload(負荷),負荷基本就是自己想要存放的資訊(因為資訊會暴露,不應該在載荷裡面加入任何敏感的資料),有兩個形式,下邊會講到
* 3.sign(簽名),簽名的作用就是為了防止惡意篡改資料
* 中間用點("\\.")分隔開,並且都會使用 Base64 編碼
*/
public final class JwtTokenUtil {
/**
* 建立token
* @param payload 負荷
* @return 簽名
* 備註:我們這裡是藉助第三方框架:jjwt實現建立token,它實際的流程是:
* 第一步:對header(頭部)進行 Base64 編碼 --------> #######
* 第二步:對payload(負荷)進行 Base64 編碼 --------> *******
* 第三步:JWT 的最後一部分是 Signature ,這部分內容有三個部分,先是用 Base64 編碼的 header.payload ,
* 再用加密演算法加密一下,加密的時候要放進去一個 Secret ,這個相當於是一個密碼,這個密碼祕密地
* 儲存在服務端。
* var encodedString = base64UrlEncode(header) + "." + base64UrlEncode(payload);
* HMACSHA256(encodedString, 'secret');
*/
public static String createToken(String payload){
System.out.println("負荷的值:" + payload);
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
//這個在實際專案中,祕鑰要配置在配置檔案中
String secretKey = "king";
byte[] secretKeyBytes = DatatypeConverter.parseBase64Binary(secretKey);
Key signKey = new SecretKeySpec(secretKeyBytes, signatureAlgorithm.getJcaName());
JwtBuilder builder = Jwts.builder()
//設定header
.setHeaderParam("typ", "JWT")
.setHeaderParam("alg", "HS256")
//設定payload
.setPayload(payload)
//簽名
.signWith(signatureAlgorithm, signKey);
return builder.compact();
}
/**
* 驗證前端傳送過來的token
* 備註:若過期,會丟擲異常
*/
public static Claims parseToken(String token){
//祕鑰
String secretKey = "king";
String[] tokens = token.split("\\.");
if (tokens.length == 3){
//header(頭部)
String header = tokens[0];
//payload(負荷)
String payload = tokens[1];
//利用Base64解碼(為什麼用Base64解碼,參見建立token)
System.out.println("負荷:" + Base64Codec.BASE64URL.decodeToString(payload));
//簽名
String sign = tokens[2];
System.out.println("簽名:" + sign);
//頭部
JwsHeader claimsHeader = Jwts.parser().setSigningKey(DatatypeConverter.parseBase64Binary(secretKey))
.parseClaimsJws(token).getHeader();
//負荷
Claims claimsPayload = Jwts.parser().setSigningKey(DatatypeConverter.parseBase64Binary(secretKey))
.parseClaimsJws(token).getBody();
String signNew = createToken(JSONObject.toJSONString(claimsPayload));
if (signNew != null && signNew.equals(token)){
System.out.println("匹配");
}
return claimsPayload;
} else {
return null;
}
}
public static void main(String[] args){
JSONObject jsonPayload = new JSONObject();
jsonPayload.put("iss", "ninghao.net");
//若過期,會丟擲異常
jsonPayload.put("exp", System.currentTimeMillis()+1000);
jsonPayload.put("name", "wanghao");
jsonPayload.put("admin", true);
String token = JwtTokenUtil.createToken(jsonPayload.toJSONString());
JwtTokenUtil.parseToken(token);
}
}