您好,登錄后才能下訂單哦!
這篇文章主要介紹“單點登錄的方式和JWT使用的方法是什么”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“單點登錄的方式和JWT使用的方法是什么”文章能幫助大家解決問題。
單點登錄的三種實現方式:
分別為session廣播機制;
cookie+redis;
token
session廣播機制指在一個集群中的一個模塊登錄后,然后把該session復制成幾份,發送到該集群的其他模塊中,可以形成在個地方登錄,其他地方不用再登錄的效果。
參與集群的每個節點的Session狀態都被復制到集群中的其他所有節點上,無論何時,只要Session發生改變,Session數據都要重新被復制。Tomcat、JBoss等都提供了這樣的功能,其中Tomcat采用集群節點廣播復制,JBoss采用配對復制機制。
Session廣播機制優缺點:
優點:每個節點都復制一份Session,一個節點出現問題時其它節點可以接替它的工作。
缺點:節點間進行Session同步會占據大量系統資源,整體性能隨著集群節點數的增加而下降。
用戶在項目的任意一個模塊登錄后,登錄之后,該模塊會將用戶的登錄信息放到兩個地方:redis 和 cookie 中。
系統會先將用戶的登錄信息存入 redis中,其在 redis 的 key 值是生成的唯一值 (可以包含 ip、用戶 id、UUID等),value 值存放用戶的登錄信息。
接著系統會將這名用戶在 redis 中的 key 值存入該用戶的 cookie 中,用戶每次訪問任意模塊時都會帶著這個 cookie。
用戶在訪問其他模塊發送請求時,會帶著客戶端的 cookie 進行請求,而客戶端的 cookie 已經存入了該用戶在 redis 中的 key 值,這樣其他模塊在處理用戶的請求時,可以先獲取用戶 cookie中的 key 值,然后拿著這個 key 值到 redis 中進行查詢,如果在 redis 中能查詢到該用戶相應的登錄信息,就說明該用戶已登錄,就不需要用戶進行重復登錄了。
token 是按照一定規則生成的字符串,字符串中可以包含用戶信息。開發人員可以自行定制這個生成規則,也可以使用提供好的生成規則(如使用 JWT 自動生成包含用戶信息的字符串)。
用戶在項目的某個模塊進行登錄后,系統會按照一定(或定制)的規則生成字符串,把用戶登錄之后的信息包含到這個生成的字符串中,然后系統可以將這個字符串返回,主要有兩種返回方式:
1.可以把字符串通過 cookie 返回;
2.可以把字符串通過地址欄返回。
這樣用戶在訪問其他的模塊時,每次訪問的地址欄都會帶著生成的字符串成字符串),然后根據字符串獲取用戶信息,如果可以獲取到用戶的登錄信息,說明該用戶已登錄,用戶就不需要重復登錄了。
JWT生成的字符串包括三部分:
1.JWT頭信息
2.有效載荷(包含頭部信息)
3.簽名哈希
JWT頭部分是一個描述JWT元數據的JSON對象,通常如下所示。
{ “alg”: “HS256”, “type”: “JWT” }
在上面的代碼中,alg屬性表示簽名使用的算法,默認為HMAC SHA256(寫為HS256);type屬性表示令牌的類型,JWT令牌統一寫為JWT。最后,使用Base64 URL算法將上述JSON對象轉換為字符串保存。
有效載荷部分,是JWT的主體內容部分,也是一個JSON對象,包含需要傳遞的數據。 JWT指定七個默認字段供選擇:
iss:發行人
exp:到期時間
sub:主題
aud:用戶
nbf:在此之前不可用
iat:發布時間
jti:JWT ID用于標識該JWT
除以上默認字段外,我們還可以自定義私有字段,如下例:
{ "sub": "1234567890", "name": "xiaowei", "admin": true }
默認情況下JWT是未加密的,任何人都可以解讀其內容,因此不要構建隱私信息字段,存放保密信息,以防止信息泄露。
JSON對象也使用Base64 URL算法轉換為字符串保存。
簽名哈希部分是對上面兩部分數據簽名,通過指定的算法生成哈希,以確保數據不會被篡改。
首先,需要指定一個密碼(secret)。該密碼僅僅為保存在服務器中,并且不能向用戶公開。然后,使用標頭中指定的簽名算法(默認情況下為HMAC SHA256)根據以下公式生成簽名。
JWT的原則
JWT的原則是在服務器身份驗證之后,將生成一個JSON對象并將其發送回用戶,如下所示。
{ "sub": "1234567890", "name": "xiaowei", "admin": true }
之后,當用戶與服務器通信時,客戶在請求中發回JSON對象。服務器僅依賴于這個JSON對象來標識用戶。為了防止用戶篡改數據,服務器將在生成對象時添加簽名。
服務器不保存任何會話數據,即服務器變為無狀態,使其更容易擴展。
JWT的用法
客戶端接收服務器返回的JWT,將其存儲在Cookie或localStorage中。
此后,客戶端將在與服務器交互中都會帶JWT。如果將它存儲在Cookie中,就可以自動發送,但是不會跨域,因此一般是將它放入HTTP請求的Header Authorization字段中。當跨域時,也可以將JWT被放置于POST請求的數據主體中。
JWT不僅可用于認證,還可用于信息交換。善用JWT有助于減少服務器請求數據庫的次數。
生產的token可以包含基本信息,比如id、用戶昵稱、頭像等信息,避免再次查庫 存儲在客戶端,不占用服務端的內存資源
JWT默認不加密,但可以加密。生成原始令牌后,可以再次對其進行加密。 當JWT未加密時,一些私密數據無法通過JWT傳輸。
JWT的最大缺點是服務器不保存會話狀態,所以在使用期間不可能取消令牌或更改令牌的權限。也就是說,一旦JWT簽發,在有效期內將會一直有效。
JWT本身包含認證信息,token是經過base64編碼,所以可以解碼,因此token加密前的對象不應該包含敏感信息,一旦信息泄露,任何人都可以獲得令牌的所有權限。為了減少盜用,JWT的有效期不宜設置太長。對于某些重要操作,用戶在使用時應該每次都進行進行身份驗證。
為了減少盜用和竊取,JWT不建議使用HTTP協議來傳輸代碼,而是使用加密的HTTPS協議進行傳輸。
<dependencies> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> </dependency> </dependencies>
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jws; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.springframework.util.StringUtils; import javax.servlet.http.HttpServletRequest; import java.util.Date; public class JwtUtils { public static final long EXPIRE = 1000 * 60 * 60 * 24; public static final String APP_SECRET = "zkdlh8Ycvxmwd9sDxzc8czxcascX9"; public static String getJwtToken(String id, String nickname){ String JwtToken = Jwts.builder() .setHeaderParam("type", "JWT") .setHeaderParam("alg", "HS256") .setSubject("guli-user") .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() + EXPIRE)) .claim("id", id) .claim("nickname", nickname) .signWith(SignatureAlgorithm.HS256, APP_SECRET) .compact(); return JwtToken; } /** * 判斷token是否存在與有效 * @param jwtToken * @return */ public static boolean checkToken(String jwtToken) { if(StringUtils.isEmpty(jwtToken)) return false; try { Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken); } catch (Exception e) { e.printStackTrace(); return false; } return true; } /** * 判斷token是否存在與有效 * @param request * @return */ public static boolean checkToken(HttpServletRequest request) { try { String jwtToken = request.getHeader("token"); if(StringUtils.isEmpty(jwtToken)) return false; Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken); } catch (Exception e) { e.printStackTrace(); return false; } return true; } /** * 根據token獲取id * @param request * @return */ public static String getMemberIdByJwtToken(HttpServletRequest request) { String jwtToken = request.getHeader("token"); if(StringUtils.isEmpty(jwtToken)) return ""; Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken); Claims claims = claimsJws.getBody(); return (String)claims.get("id"); } }
關于“單點登錄的方式和JWT使用的方法是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。