使用JWT 进行基于 Token 的身份验证方法
一般weby应用服务都使用有状态的session来存储用户状态以便认证有权限的用户进行的操作。但服务器在做横向扩展时,这种有状态的session解决方案就受到了限制。所以在一些通常的大型web应用场景越来越多在采用没有状态的token来进行用户签权处理。
需要把Web应用做成无状态的,即服务器端无状态,就是说服务器端不会存储像会话这种东西,而是每次请求时access_token进行资源访问。这里我们将使用 JWT 1,基于散列的消息认证码,使用一个密钥和一个消息作为输入,生成它们的消息摘要。该密钥只有服务端知道。访问时使用该消息摘要进行传播,服务端然后对该消息摘要进行验证。
认证步骤
1.客户端第一次使用用户名密码访问认证服务器,服务器验证用户名和密码,认证成功,使用用户密钥生成JWT并返回
2.之后每次请求客户端带上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); }
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。