簡(jiǎn)單記錄一下和第三方對(duì)接的文件的上傳下載驗(yàn)證設(shè)計(jì)
工作以來(lái)還是第一次做這種加密和驗(yàn)證類的程序設(shè)計(jì)遗契,初版應(yīng)該還有很多不足,簡(jiǎn)單總結(jié)一下病曾,方便后續(xù)的回顧和迭代牍蜂。
拿到這個(gè)需求后我能考慮到的點(diǎn)有以下幾個(gè)
1、登錄驗(yàn)證機(jī)制泰涂。
2鲫竞、密碼傳輸?shù)募用艽胧?/p>
3、多線程安全和程序的可復(fù)用可擴(kuò)展逼蒙。
設(shè)計(jì)思路如下
用戶發(fā)送請(qǐng)求——服務(wù)端返回公鑰
用戶對(duì)密碼進(jìn)行加密——登錄驗(yàn)證請(qǐng)求——返回token
用戶存儲(chǔ)token并攜帶再請(qǐng)求頭中——上傳和下載贡茅。
其中應(yīng)用到的主要技術(shù)有 :
1、RSA算法加密
2、MD5算法簽名認(rèn)證加密
3顶考、JWT的token生成和驗(yàn)證機(jī)制
4赁还、spring基礎(chǔ)應(yīng)用
RSA算法總結(jié)過(guò)了不再贅述,MD5加密技術(shù)也比較老也不贅述了
這里總結(jié)一下JWT的token實(shí)現(xiàn)機(jī)制
1驹沿、生成一個(gè)秘鑰
2艘策、生成token
/**
* 生成token,該方法只在用戶登錄成功后調(diào)用
*
* @param Map集合渊季,可以存儲(chǔ)用戶id朋蔫,token生成時(shí)間,token過(guò)期時(shí)間等自定義字段
* @return token字符串,若失敗則返回null
*/
public static String createToken(Map<String, Object> payload) {
String tokenString = null;
// 創(chuàng)建一個(gè) JWS object
JWSObject jwsObject = new JWSObject(header, new Payload(new JSONObject(payload)));
try {
// 將jwsObject 進(jìn)行HMAC簽名
jwsObject.sign(new MACSigner(SECRET));
tokenString = jwsObject.serialize();
} catch (JOSEException e) {
System.err.println("簽名失敗:" + e.getMessage());
e.printStackTrace();
}
return tokenString;
}
3却汉、驗(yàn)證token
/**
* 校驗(yàn)token是否合法驯妄,返回Map集合,集合中主要包含 state狀態(tài)碼 data鑒權(quán)成功后從token中提取的數(shù)據(jù)
* 該方法在過(guò)濾器中調(diào)用,每次請(qǐng)求API時(shí)都校驗(yàn)
*
* @param token
* @return Map<String, Object>
*/
public static Map<String, Object> validToken(String token) {
Map<String, Object> resultMap = new HashMap<String, Object>();
try {
JWSObject jwsObject = JWSObject.parse(token);
Payload payload = jwsObject.getPayload();
JWSVerifier verifier = new MACVerifier(SECRET);
if (jwsObject.verify(verifier)) {
JSONObject jsonOBj = payload.toJSONObject();
// token校驗(yàn)成功(此時(shí)沒(méi)有校驗(yàn)是否過(guò)期)
resultMap.put("state", TokenState.VALID.toString());
// 若payload包含ext字段合砂,則校驗(yàn)是否過(guò)期
if (jsonOBj.containsKey("ext")) {
long extTime = Long.valueOf(jsonOBj.get("ext").toString());
long curTime = new Date().getTime();
// 過(guò)期了
if (curTime > extTime) {
resultMap.clear();
resultMap.put("state", TokenState.EXPIRED.toString());
}
}
resultMap.put("data", jsonOBj);
} else {
// 校驗(yàn)失敗
resultMap.put("state", TokenState.INVALID.toString());
}
} catch (Exception e) {
// e.printStackTrace();
// token格式不合法導(dǎo)致的異常
resultMap.clear();
resultMap.put("state", TokenState.INVALID.toString());
}
return resultMap;
}
這里進(jìn)行一下思路的擴(kuò)展
1青扔、加密