Http協(xié)議是無狀態(tài)的拉讯,一次請求結(jié)束蛔趴,連接斷開挑辆,下次服務(wù)器再收到請求,它就不知道這個請求是哪個用戶發(fā)過來的孝情。但是對我們的應(yīng)用而言鱼蝉,它是需要有狀態(tài)管理的,以便服務(wù)端能夠準確的知道Http請求是哪個用戶發(fā)起的箫荡,從而判斷他是否有權(quán)限繼續(xù)這個請求魁亦。這個過程就是常說的會話管理。
本文總結(jié)了3種常見的實現(xiàn)web應(yīng)用會話管理的方式:
- 基于session
- 基于公鑰/私鑰
- 基于token
一羔挡、基于Session
Session就不用多說了洁奈,至于分布式Session實現(xiàn)方案 Java中通過Spring Session可以很方便的實現(xiàn)分布式Session管理间唉。
二、基于公鑰/私鑰
事先給客戶端分配一個app_id和app_secret利术,客戶端調(diào)用接口的時候?qū)I(yè)務(wù)參數(shù)按字母排序呈野,首尾加app_secret再RSA2(推薦使用SHA256,MD5和SHA1已被攻破)生成前面sign印叁,然后再將業(yè)務(wù)參數(shù)和sign發(fā)送給服務(wù)器被冒,服務(wù)器端用相同的方式生成sign,如果sign相等則路由到業(yè)務(wù)方法喉钢,否則返回鑒權(quán)失敗姆打。
示例代碼如下:
private static final String UTF_8 = "UTF-8";
public static String encode(Map<String, String> param, String secret, boolean encode) {
Set<String> keysSet = param.keySet();
Object[] keys = keysSet.toArray();
Arrays.sort(keys); //按參數(shù)名字典順序排序
StringBuilder sb = new StringBuilder(1024);
for(int i=0; i<keys.length; i++) {
if(i!=0){
sb.append("&");
}
sb.append(keys[i]).append("=");
String value = param.get(keys[i]);
String valueString = "";
if (null != value) {
valueString = value;
}
if (encode) {
sb.append(urlEncode(valueString));
} else {
sb.append(valueString);
}
}
sb.append(secret);
return DigestUtils.sha256Hex(sb.toString());
}
private static String urlEncode(String str) {
try {
return URLEncoder.encode(str, UTF_8);
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException("unsupported encoding:"+UTF_8, e);
}
}
三、基于token
服務(wù)端動態(tài)生成token肠虽,客戶端調(diào)用的時候需要回傳token幔戏,參考 微信公共平臺 access_token
3.1 JWT
JWT
參考資料
螞蟻金服開發(fā)平臺 簽名與驗簽
微信公共平臺 access_token
通過Spring Session實現(xiàn)新一代的Session管理