當(dāng)前位置:首頁 > 芯聞號 > 充電吧
[導(dǎo)讀]上一篇文章講解了JWT的基本簡介,這一篇文章我就來實戰(zhàn)一下。介紹一下在分布式單點登錄中的使用方法:首先來看一下Token實體類,public?class?Token?implements?Serial


上一篇文章講解了JWT的基本簡介,這一篇文章我就來實戰(zhàn)一下。介紹一下在分布式單點登錄中的使用方法:


首先來看一下Token實體類,


public?class?Token?implements?Serializable{
	private?static?final?long?serialVersionUID?=?-5391652691006115018L;
	
	/**?認(rèn)證頭?**/
	private?Head?head;
	/**?認(rèn)證信息有效載荷?**/
	private?Playload?playload;
	
	/**?第一部分:base64head頭?**/
	private?String?base64Head;
	/**?第二部分:base64playload荷載?**/
	private?String?base64PlayLoad;
	/**?第三部分:簽證信息?**/
	private?String?signature;
	/**?最終token字符串?**/
	private?String?tokenStr;
	
	/**
	?*?Token頭
	?*
	?*
	?*/
	public?static?class?Head?implements?Serializable{
		private?static?final?long?serialVersionUID?=?-6516084948347601103L;
		
		/**?token類型?**/
		private?String?typ?=?"JWT";
		/**?token算法?默認(rèn):HMAC?SHA256**/
		private?String?alg?=?"HS256";
		
		public?String?getTyp()?{
			return?typ;
		}
		public?void?setTyp(String?typ)?{
			this.typ?=?typ;
		}
		public?String?getAlg()?{
			return?alg;
		}
		public?void?setAlg(String?alg)?{
			this.alg?=?alg;
		}
	}
	
	/**
	?*?Token有效載荷
	?*?
	?*
	?*/
	public?static?class?Playload?implements?Serializable?{
		private?static?final?long?serialVersionUID?=?3981890375700111920L;
		
		/**?該token簽發(fā)者?**/
		private?String?iss;
		/**?該token的所有人,可以存放用戶名?**/
		private?String?sub;
		/**?接收token的一方?**/
		private?String?aud;
		/**?token的過期時間(時間戳),必須要大于簽發(fā)時間;大于等于該時間需要刷新token?**/
		private?long?exp;
		/**?token生效的開始時間(時間戳),意味著在這個時間之前驗證token是會失敗的,默認(rèn)生成token后立即生效?**/
		private?long?nbf;
		/**?token的簽發(fā)時間?時間戳**/
		private?long?iat;
		/**?token的唯一身份標(biāo)識,主要用來作為一次性token,從而回避重放攻擊?**/
		private?String?jti;
		/**?token驗證寬限時間(時間戳)?超過寬限時間需要重新登錄,??
		?*?即該token的真正存活時間,寬限時間的加入是為了解決并發(fā)token刷新后新token失效問題
		?*?**/
		private?long?gra;
		/**?token類型:??后臺登錄用戶,互聯(lián)網(wǎng)用戶,第三方機構(gòu)?**/
		private?String?typ;
		
		public?String?getIss()?{
			return?iss;
		}
		public?void?setIss(String?iss)?{
			this.iss?=?iss;
		}
		public?String?getSub()?{
			return?sub;
		}
		public?void?setSub(String?sub)?{
			this.sub?=?sub;
		}
		public?String?getAud()?{
			return?aud;
		}
		public?void?setAud(String?aud)?{
			this.aud?=?aud;
		}
		public?long?getExp()?{
			return?exp;
		}
		public?void?setExp(long?exp)?{
			this.exp?=?exp;
		}
		public?long?getNbf()?{
			return?nbf;
		}
		public?void?setNbf(long?nbf)?{
			this.nbf?=?nbf;
		}
		public?long?getIat()?{
			return?iat;
		}
		public?void?setIat(long?iat)?{
			this.iat?=?iat;
		}
		public?String?getJti()?{
			return?jti;
		}
		public?void?setJti(String?jti)?{
			this.jti?=?jti;
		}
		public?long?getGra()?{
			return?gra;
		}
		public?void?setGra(long?gra)?{
			this.gra?=?gra;
		}
		public?String?getTyp()?{
			return?typ;
		}
		public?void?setTyp(String?typ)?{
			this.typ?=?typ;
		}

		
	}

	public?Head?getHead()?{
		return?head;
	}
	public?void?setHead(Head?head)?{
		this.head?=?head;
	}
	public?Playload?getPlayload()?{
		return?playload;
	}
	public?void?setPlayload(Playload?playload)?{
		this.playload?=?playload;
	}
	public?String?getSignature()?{
		return?signature;
	}
	public?void?setSignature(String?signature)?{
		this.signature?=?signature;
	}
	public?String?getBase64Head()?{
		return?base64Head;
	}
	public?void?setBase64Head(String?base64Head)?{
		this.base64Head?=?base64Head;
	}
	public?String?getBase64PlayLoad()?{
		return?base64PlayLoad;
	}
	public?void?setBase64PlayLoad(String?base64PlayLoad)?{
		this.base64PlayLoad?=?base64PlayLoad;
	}
	public?String?getTokenStr()?{
		return?tokenStr;
	}
	public?void?setTokenStr(String?tokenStr)?{
		this.tokenStr?=?tokenStr;
	}
	
}



可以看到實體類里面包含了head payload signature這三部分。

然后用戶登錄成功之后創(chuàng)建token的代碼如下:


public?static?Token?createToken(String?secret,String?tokenId,TokenType?tokenType,String?userName)?{
		try?{
			Token?token?=?new?Token();
			//創(chuàng)建頭
			Token.Head?head?=?new?Token.Head();
			head.setAlg("HS256");
			head.setTyp("JWT");
			
			//創(chuàng)建載荷
			//簽發(fā)時間
			long?iat?=?System.currentTimeMillis();
			//過期時間?20?分鐘后過期
			long?exp?=?iat?+?AuthConstants.TOKEN_EXP_TIME?;
			//最后存活時間
			long?gra?=?iat?+?AuthConstants.TOKEN_GRA_TIME?;
			Token.Playload?playload?=?new?Token.Playload();
			playload.setAud("CLIENT");?//接收token的一方
			playload.setIat(iat);?//簽發(fā)時間
			playload.setExp(exp);
			playload.setGra(gra);
			playload.setIss("AUTH_CENTER");//簽發(fā)者
			playload.setJti(tokenId);?//token唯一身份標(biāo)識
			playload.setNbf(iat);//生效時間,立即生效
			playload.setSub(userName);?//token的所屬者,可以存放用戶名
			playload.setTyp(tokenType.toString().toUpperCase());
			
			//創(chuàng)建token
			String?base64Head?=?Base64Util.encodeStr(JSONUtil.toJson(head)?);
			String?base64Playload?=?Base64Util.encodeStr(JSONUtil.toJson(playload)?);
			String?signature?=?HmacUtil.encryptHMACSHA256(base64Head+"."+base64Playload,?secret);?//token簽名
			String?tokenStr?=?base64Head+"."+base64Playload+"."+signature;?//token字符串
			
			//組裝token對象
			token.setHead(head);
			token.setPlayload(playload);
			token.setBase64Head(base64Head);
			token.setBase64PlayLoad(base64Playload);
			token.setSignature(signature);
			token.setTokenStr(tokenStr);
			return?token;
		}?catch?(Exception?e)?{
			e.printStackTrace();
			logger.error("生成token失敗:{}",e.getMessage());
		}
		return?null;
	}



創(chuàng)建成功之后,要把token放到響應(yīng)頭中,setHeader方法name參數(shù)要用Authorization,value值要使用

"Bearer "+token。

然后用戶訪問需要權(quán)限的接口都需要在請求頭加上token,因為使用了Spring Cloud微服務(wù)架構(gòu),因此請求

會統(tǒng)一通過API網(wǎng)關(guān)訪問,所以需要在網(wǎng)關(guān)處驗證token的合法性,使用下面這個parseToken的方法:


/**
	?*?驗證并解析token
	?*?@param?token?token字符串
	?*?@param?secret?token簽名的鹽(密鑰)
	?*?@return?成功返回token?,失敗返回ull
	?*/
	public?static?Token?parseToken(String?token,String?secret)?{
		try?{
			//判斷token是否是合法格式的token串
			if(StringUtils.isEmpty(token))?{
				throw?new?AuthException("token串為空!");
			}
			if(StringUtils.isEmpty(secret))?{
				throw?new?AuthException("解析token時,token密鑰為空!");
			}
			String[]?tokens?=?token.split("\.");
			if(tokens==null?||?tokens.length!=3)?{
				throw?new?AuthException("非法格式的token串:"+token);
			}
			
			//token分解
			String?base64Head?=?tokens[0].trim();?//token頭
			String?base64Playload?=?tokens[1].trim();?//token載荷
			String?signature?=?tokens[2].trim();?//token簽名
			//驗證簽名是否為合法的
			String?signData?=?base64Head+"."+base64Playload;
			String?signaturedStr?=?HmacUtil.encryptHMACSHA256(signData,?secret.trim());?//token簽名
			if(!signature.equals(signaturedStr))?{
				throw?new?AuthException("非法的token:解析token時,token驗簽失敗!");
			}
			
			Token.Head?head?=?JSONUtil.toBean(Base64Util.decodeStr(base64Head),?Token.Head.class);
			Token.Playload?playLoad?=?JSONUtil.toBean(Base64Util.decodeStr(base64Playload),?Token.Playload.class);
			Token?rs?=?new?Token();
			rs.setHead(head);
			rs.setPlayload(playLoad);
			rs.setSignature(signature);
			return?rs;
		}?catch?(Exception?e)?{
			e.printStackTrace();
			logger.error("解析token失敗:{}",e.getMessage());
			return?null;
		}
	}



使用JWT進行身份驗證的基本方法的實例就到這里,沒有接觸過JWT的同學(xué)可以先看一下JWT


本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉