您好,登錄后才能下訂單哦!
一般weby應(yīng)用服務(wù)都使用有狀態(tài)的session來(lái)存儲(chǔ)用戶狀態(tài)以便認(rèn)證有權(quán)限的用戶進(jìn)行的操作。但服務(wù)器在做橫向擴(kuò)展時(shí),這種有狀態(tài)的session解決方案就受到了限制。所以在一些通常的大型web應(yīng)用場(chǎng)景越來(lái)越多在采用沒(méi)有狀態(tài)的token來(lái)進(jìn)行用戶簽權(quán)處理。
需要把Web應(yīng)用做成無(wú)狀態(tài)的,即服務(wù)器端無(wú)狀態(tài),就是說(shuō)服務(wù)器端不會(huì)存儲(chǔ)像會(huì)話這種東西,而是每次請(qǐng)求時(shí)access_token進(jìn)行資源訪問(wèn)。這里我們將使用 JWT 1,基于散列的消息認(rèn)證碼,使用一個(gè)密鑰和一個(gè)消息作為輸入,生成它們的消息摘要。該密鑰只有服務(wù)端知道。訪問(wèn)時(shí)使用該消息摘要進(jìn)行傳播,服務(wù)端然后對(duì)該消息摘要進(jìn)行驗(yàn)證。
認(rèn)證步驟
1.客戶端第一次使用用戶名密碼訪問(wèn)認(rèn)證服務(wù)器,服務(wù)器驗(yàn)證用戶名和密碼,認(rèn)證成功,使用用戶密鑰生成JWT并返回
2.之后每次請(qǐng)求客戶端帶上JWT
3.服務(wù)器對(duì)JWT進(jìn)行驗(yàn)證
首先使用JWTUtil類 來(lái)完成生成token和驗(yàn)證token的工作
public class JwtUtil {
private static String SECRET = "com.mozi.shop.secret";
private static String ISSUER = "MoziShop";
/**
* 生成token
*
* @param claims
* @return
*/
public static String createToken(Map<String, String> claims) throws Exception {
try {
Algorithm algorithm = Algorithm.HMAC256(SECRET);
JWTCreator.Builder builder = JWT.create()
.withIssuer(ISSUER)
//設(shè)置過(guò)期時(shí)間為2小時(shí)
.withExpiresAt(DateUtils.addHours(new Date(), 2));
claims.forEach(builder::withClaim);
return builder.sign(algorithm);
} catch (Exception e) {
throw new Exception("生成token失敗");
}
}
/**
* 驗(yàn)證jwt,并返回?cái)?shù)據(jù)
*/
public static Map<String, String> verifyToken(String token) throws Exception {
Algorithm algorithm;
Map<String, Claim> map;
try {
Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
JWTVerifier verifier = JWT.require(algorithm).build();
DecodedJWT jwt = verifier.verify(token);
return true;*/
///
algorithm = Algorithm.HMAC256(SECRET);
JWTVerifier verifier = JWT.require(algorithm).withIssuer(ISSUER).build();
//JWTVerifier verifier = JWT.require(algorithm).build();
DecodedJWT jwt = verifier.verify(token);
map = jwt.getClaims();
} catch (Exception e) {
throw new Exception("鑒權(quán)失敗");
}
Map<String, String> resultMap = new HashMap<>(map.size());
map.forEach((k, v) -> resultMap.put(k, v.asString()));
return resultMap;
}
}
在用戶進(jìn)行正常登錄操作時(shí)返回客戶端一個(gè)和失效時(shí)間的token
/**
* 登錄頁(yè)面
*/
public void index(){
String username = getPara("username");
String password = getPara("password");
// System.out.println("LOGIN USERNAME:"+username);
if(StringUtils.isNotBlank(username) && StringUtils.isNotBlank(password)){
Member member = new Member().dao().findByUsername(username);
if(member == null){
//setAttr("feedback", Feedback.error("用戶不存在"));
setAttr("feedback", "用戶不存在");
//System.out.println("LOGIN USERNAME 用戶不存在:"+username);
render("/templates/"+getTheme()+"/"+getDevice()+"/login.html");
return;
}else if(!DigestUtils.md5Hex(password).equals(member.getPassword())){
//setAttr("feedback", Feedback.error("用戶名密碼錯(cuò)誤"));
setAttr("feedback", "用戶名密碼錯(cuò)誤");
render("/templates/"+getTheme()+"/"+getDevice()+"/login.html");
return;
}else{
/////jwt start///////////////////////////////////////////
Map<String, String> map = new HashMap<>();
map.put("id", (member.getId()).toString());
map.put("name", member.getUsername());
map.put("openid", member.getWeixinOpenId());
String token = null;
try {
token = JwtUtil.createToken(map);
}catch (Exception e) {
}
this.getResponse().setHeader("token", token);
/////jwt end////////////////////////////////////////////
redirect("/");
return;
}
}else{
System.out.println("nousername and pwd!!!!!!!!!!!!!!!");
render("/templates/"+getTheme()+"/"+getDevice()+"/login.html");
}
}
然后在需要授權(quán)的訪問(wèn)中鑒定用戶攜帶的token,驗(yàn)證有效就進(jìn)行操作
String token = getRequest().getHeader("token");
try {
Map<String, String> res = JwtUtil.verifyToken(token);
System.out.println(JSON.toJSONString(res));
}catch (Exception e) {
System.out.println(e);
}
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。