詳解JWT token心得與使用實例
本文你能學(xué)到什么?
token的組成
token串的生成流程。
token在客戶端與服務(wù)器端的交互流程
Token的優(yōu)點和思考
參考代碼:核心代碼使用參考,不是全部代碼
JWT token的組成
頭部(Header),格式如下:
{
“typ”: “JWT”,
“alg”: “HS256”
}
由上可知,該token使用HS256加密算法,將頭部使用Base64編碼可得到如下個格式的字符串:
eyJhbGciOiJIUzI1NiJ9
有效載荷(Playload):
{
“iss”: “Online JWT Builder”,
“iat”: 1416797419,
“exp”: 1448333419,
…….
“userid”:10001
}
有效載荷中存放了token的簽發(fā)者(iss)、簽發(fā)時間(iat)、過期時間(exp)等以及一些我們需要寫進token中的信息。有效載荷也使用Base64編碼得到如下格式的字符串:
eyJ1c2VyaWQiOjB9
簽名(Signature):
將Header和Playload拼接生成一個字符串str=“eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyaWQiOjB9”,使用HS256算法和我們提供的密鑰(secret,服務(wù)器自己提供的一個字符串)對str進行加密生成最終的JWT,即我們需要的令牌(token),形如:str.”簽名字符串”。
token在服務(wù)與客戶端的交互流程
1:客戶端通過用戶名和密碼登錄
2:服務(wù)器驗證用戶名和密碼,若通過,生成token返回給客戶端。
3:客戶端收到token后以后每次請求的時候都帶上這個token,相當(dāng)于一個令牌,表示我有權(quán)限訪問了
4:服務(wù)器接收(通常在攔截器中實現(xiàn))到該token,然后驗證該token的合法性(為什么能驗證下面說)。若該token合法,則通過請求,若token不合法或者過期,返回請求失敗。
關(guān)于Token的思考
服務(wù)如何判斷這個token是否合法?
由上面token的生成可知,token中的簽名是由Header和有效載荷通過Base64編碼生成再通過加密算法HS256和密鑰最終生成簽名,這個簽名位于JWT的尾部,在服務(wù)器端同樣對返回過來的JWT的前部分再進行一次簽名生成,然后比較這次生成的簽名與請求的JWT中的簽名是否一致,若一致說明token合法。由于生成簽名的密鑰是服務(wù)器才知道的,所以別人難以偽造。
token中能放敏感信息嗎?
不能,因為有效載荷是經(jīng)過Base64編碼生成的,并不是加密。所以不能存放敏感信息。
Token的優(yōu)點
(1)相比于session,它無需保存在服務(wù)器,不占用服務(wù)器內(nèi)存開銷。
(2)無狀態(tài)、可拓展性強:比如有3臺機器(A、B、C)組成服務(wù)器集群,若session存在機器A上,session只能保存在其中一臺服務(wù)器,此時你便不能訪問機器B、C,因為B、C上沒有存放該Session,而使用token就能夠驗證用戶請求合法性,并且我再加幾臺機器也沒事,所以可拓展性好就是這個意思。
(3)由(2)知,這樣做可就支持了跨域訪問。
Java實例:JWT token使用
部分代碼來自互聯(lián)網(wǎng),找不到原作者了。。
編寫JWT(Java Web Token)操作類:JavaWebToken
public class JavaWebToken {
private static Logger log = LoggerFactory.getLogger(JavaWebToken.class);
//該方法使用HS256算法和Secret:bankgl生成signKey
private static Key getKeyInstance() {
//We will sign our JavaWebToken with our ApiKey secret
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary("bankgl");
Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
return signingKey;
}
//使用HS256簽名算法和生成的signingKey最終的Token,claims中是有效載荷
public static String createJavaWebToken(Map<String, Object> claims) {
return Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS256, getKeyInstance()).compact();
}
//解析Token,同時也能驗證Token,當(dāng)驗證失敗返回null
public static Map<String, Object> parserJavaWebToken(String jwt) {
try {
Map<String, Object> jwtClaims =
Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwt).getBody();
return jwtClaims;
} catch (Exception e) {
log.error("json web token verify failed");
return null;
}
}
}
編寫登錄Conreoller,在服務(wù)器端給客戶返回token.
public LoginStatusMessage checkUserAndPassword(
@RequestParam(value="username",required=true) String username,
@RequestParam(value="password",required=true) String password,User user,HttpServletRequest request) throws Exception{
User u = new User();
//登錄成功
if((u = userService.checkUsernameAndPassword(user)) != null){
Map<String,Object> m = new HashMap<String,Object>();
m.put("userid", user.getUserid());
String token = JavaWebToken.createJavaWebToken(m);
System.out.println(token);
LoginStatusMessage lsm = new LoginStatusMessage();
lsm.setUser(u);
lsm.setToken(token);
return lsm;
};
//登錄失敗,返回Null
return null;
}
在攔截器中對請求中的Token驗證(部分代碼,表示下意思):
String token = request.getParameter("token");
if(JavaWebToken.parserJavaWebToken(token) != null){
//表示token合法
return true;
}else{
//token不合法或者過期
return false;
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript 實現(xiàn)模態(tài)對話框 源代碼大全
對話框在Windows應(yīng)用程序中使用非常普遍,許多應(yīng)用程序的設(shè)定,與用戶交互需要通過對話框來進行,因此對話框是Windows應(yīng)用程序中最重要的界面元素之一,是與用戶交互的重要手段。2009-05-05
使用JavaScript實現(xiàn)改造layer彈層移動版組件
這篇文章主要為大家詳細(xì)介紹了使用JavaScript實現(xiàn)改造layer彈層移動版組件的相關(guān)知識,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-04-04
javascript實現(xiàn)動態(tài)表頭及表列的展現(xiàn)方法
這篇文章主要介紹了javascript實現(xiàn)動態(tài)表頭及表列的展現(xiàn)方法,涉及javascript動態(tài)操作table元素的實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-07-07

