使用JWT 進行基於 Token 的身份驗證方法
阿新 • • 發佈:2019-05-08
quest 傳播 token system 過期 with 需要 驗證用戶名 ren 一般weby應用服務都使用有狀態的session來存儲用戶狀態以便認證有權限的用戶進行的操作。但服務器在做橫向擴展時,這種有狀態的session解決方案就受到了限制。所以在一些通常的大型web應用場景越來越多在采用沒有狀態的token來進行用戶簽權處理。
2.之後每次請求客戶端帶上JWT
3.服務器對JWT進行驗證
需要把Web應用做成無狀態的,即服務器端無狀態,就是說服務器端不會存儲像會話這種東西,而是每次請求時access_token進行資源訪問。這裏我們將使用 JWT 1,基於散列的消息認證碼,使用一個密鑰和一個消息作為輸入,生成它們的消息摘要。該密鑰只有服務端知道。訪問時使用該消息摘要進行傳播,服務端然後對該消息摘要進行驗證。
認證步驟
1.客戶端第一次使用用戶名密碼訪問認證服務器,服務器驗證用戶名和密碼,認證成功,使用用戶密鑰生成JWT並返回
3.服務器對JWT進行驗證
首先使用JWTUtil類 來完成生成token和驗證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) //設置過期時間為2小時 .withExpiresAt(DateUtils.addHours(new Date(), 2)); claims.forEach(builder::withClaim); return builder.sign(algorithm); } catch (Exception e) { throw new Exception("生成token失敗"); } } /** * 驗證jwt,並返回數據 */ 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("鑒權失敗"); } Map<String, String> resultMap = new HashMap<>(map.size()); map.forEach((k, v) -> resultMap.put(k, v.asString())); return resultMap; } }
在用戶進行正常登錄操作時返回客戶端一個和失效時間的token
/** * 登錄頁面 */ 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("用戶名密碼錯誤")); setAttr("feedback", "用戶名密碼錯誤"); 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"); } }
然後在需要授權的訪問中鑒定用戶攜帶的token,驗證有效就進行操作
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);
}
使用JWT 進行基於 Token 的身份驗證方法