無狀態session 解決方案 JWT

2021-08-20 21:19:22 字數 3202 閱讀 3002

現在分布式微服務的逐漸使用廣泛,前後端分離已經成為網際網路專案開發標準,它會為以後的大型分布式架構打下基礎。為以後服務的橫向擴充套件提供了方便

json web tokens

(jwt)能提供基於json格式的安全認證。jwt可以跨不同語言,自帶身份資訊,並且非常容易傳遞。

jwt即json web token的縮寫,輕量級的令牌認證(相比於oauth),可用於資料交換間的安全傳輸,同時可使用公鑰/私鑰的非對稱演算法對資訊進行數字簽名,如rs256演算法。

它由3部分組成:

使用場景:

1、單點登入,此場景也是使用最廣的一種,流程原理很簡單:使用者登入成功-》生成token返回前端並儲存(cookie或localstorage)-》之後每次請求在header或body中帶此token-》伺服器驗證此token以保證資料合法性

官方給的單點登入流程圖

優點:jwt是基於json格式的資料安全認證,可以跨平台、跨語言、自帶身份資訊、非常容易傳遞

缺點:jwt涉及base64及加密處理,所以會使傳輸的資料會比裸傳資料大很多,這方面大家可以根據實際情況做平衡取捨。對於公司內部的專案及對傳輸資料量有極高要求的更要慎重考慮用jwt方式;

和session方式儲存id的差異

session方式儲存使用者id的最大弊病在於session是儲存在伺服器端的,所以需要占用大量伺服器記憶體,對於較大型應用而言可能還要儲存許多的狀態。一般而言,大型應用還需要借助一些kv資料庫和一系列快取機制來實現session的儲存。

而jwt方式將使用者狀態分散到了客戶端中,可以明顯減輕服務端的記憶體壓力。除了使用者id之外,還可以儲存其他的和使用者相關的資訊,例如該使用者是否是管理員、使用者所在的分組等。雖說jwt方式讓伺服器有一些計算壓力(例如加密、編碼和解碼),但是這些壓力相比磁碟儲存而言可能就不算什麼了。具體是否採用,需要在不同場景下用資料說話。

實戰部分

建立實體類    

@component

public class jwt " )

private string secret;

/*** 有效時間

*/@value( "$" )

private long expire;

/*** 使用者憑證

*/@value( "$" )

private string header;

/*** 獲取:加密秘鑰

*/public string getsecret()

/*** 設定:加密秘鑰

*/public void setsecret(string secret)

/*** 獲取:有效期(s)

* */

public long getexpire()

/*** 設定:有效期(s)

* */

public void setexpire(long expire)

/*** 獲取:憑證

* */

public string getheader()

/*** 設定:憑證

* */

public void setheader(string header)

/*** 生成token簽名

* @param userid 使用者id

* @return 簽名字串

*/public string generatetoken(long userid)

/*** 獲取簽名資訊

* @param token

*/public claims getclaimbytoken(string token) catch (exception e)

}/**

* 判斷token是否過期

* @param expiration

* @return true 過期

*/public boolean istokenexpired(date expiration)

}

@component

public class jwtinterceptor extends handlerinterceptoradapter

// 需要驗證

string token = gettoken(request);

if (stringutils.isblank(token))

// 獲取簽名資訊

claims claims = jwt.getclaimbytoken(token);

system.out.println("token: " + claims);

// 判斷簽名是否存在或過期

boolean b = claims==null || claims.isempty() || jwt.istokenexpired(claims.getexpiration());

if (b)

// 將簽名中獲取的使用者資訊放入request中;

request.setattribute(user_key, claims.getsubject());

return true;

}/**

* 根據url判斷當前請求是否需要校驗, true:需要校驗

*/private boolean ischeck(string servletpath)

// }

return false;

}/**

* 獲取請求token

* 不用攔截的頁面路徑(也可存入資料庫中)

*/private static final string not_check_url = {};

}

講***註冊到spring中

@configuration

public class webconfig extends webmvcconfigureradapter

/***

* */

@override

public void addinterceptors(interceptorregistry registry)

}

集群 Session解決方案

在集群中session安全和同步是個最大的問題,下面是收集到的幾種session同步的方案,希望能通過分析其各自的優劣找出其適應的場景。1.客戶端cookie加密 簡單,高效。比較好的方法是自己採用cookie機制來實現乙個session,在應用中使用此session實現。問題 session中資料...

session共享解決方案

做負載均衡和伺服器集群時,往往會遇到session同步的問題,下面是蒐羅的幾種可行的解決方案,僅供參考。下面是三種不同的解決方案,如果哪位大神有更好的方案,請分享給我,小弟感激不盡 一 專門建乙個資料庫來存session或者單獨建乙個表 每次從資料庫取session,但是如果做了mysql集群,每個...

集群 Session解決方案

在集群中session安全和同步是個最大的問題,下面是收集到的幾種session同步的方案,希望能通過分析其各自的優劣找出其適應的場景。1.客戶端cookie加密 簡單,高效。比較好的方法是自己採用cookie機制來實現乙個session,在應用中使用此session實現。問題 session中資料...