JavaWeb JWT使用 JJWT
1.设计JwtUtil 生成、鉴定
生成token
public static String generateToken(int id,String username,Date generateTime) { //根据产生时间
HashMap<String, Object> map = new HashMap<>();
//可以把任何安全的数据放到map里面
map.put("id", username);
map.put("username", username);
map.put("generateTime",generateTime);
String jwt = Jwts.builder()
.setClaims(map)
.setExpiration(new Date(generateTime.getTime() + EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS512, SECRET)
.compact();
return jwt;
}
检验token
public static Map<String,Object> validateToken(String token) {
Map<String,Object> resp = new HashMap<String,Object>();
if (token != null) {
// 解析token
try {
Map<String, Object> body = Jwts.parser() //根据Token解析出来时间 和 用户名
.setSigningKey(SECRET)
.parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
.getBody();
int id=(int)(body.get("id"));
String username = (String) (body.get("username"));
Date generateTime = new Date((Long)body.get("generateTime"));
if(username == null || username.isEmpty()){
resp.put("ERR_MSG",Constants.ERR_MSG_USERNAME_EMPTY);
return resp;
}
if((new UserDaoImpl().getUser(id)).getLastLoginTime().after(generateTime)){
resp.put("ERR_MSG",Constants.ERR_MSG_LOGIN_DOU);
return resp;
}
resp.put("id",id);
resp.put("username",username);
resp.put("generateTime",generateTime);
return resp;
}catch (SignatureException | MalformedJwtException e) {
// TODO: handle exception
// don't trust the JWT!
// jwt 解析错误
resp.put("ERR_MSG",Constants.ERR_MSG_TOKEN_ERR);
return resp;
} catch (ExpiredJwtException e) {
// TODO: handle exception
// jwt 已经过期,在设置jwt的时候如果设置了过期时间,这里会自动判断jwt是否已经过期,如果过期则会抛出这个异常,我们可以抓住这个异常并作相关处理。
resp.put("ERR_MSG",Constants.ERR_MSG_TOKEN_EXP);
return resp;
}
}else {
resp.put("ERR_MSG",Constants.ERR_MSG_TOKEN_EMPTY);
return resp;
}
}
2.在user login中加入token生成
private IUserDao loginDao = (IUserDao) new UserDaoImpl();
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
String tel = request.getParameter("tel");
String pwd = request.getParameter("pwd");
// 用户登录验证
User login = loginDao.login(tel, pwd);
//判断用户是否登录 如果已经登录记录下用户id、用户名 通过tel 账号 pwd 密码 登陆
if(login==null){
out.println("-1");
}else{
login.setLastLoginTime(new Date());
//每一次 登陆就生成一个Token 用token去访问接口
login.setToken(JwtUtil.generateToken(login.getId(),tel,login.getLastLoginTime()));
String token=login.getToken();
String userMsg = "";
userMsg+="id="+login.getId();
userMsg+=";";
userMsg+="tel="+login.getMobilephone();
userMsg+=";";
userMsg+="token="+token;
out.println(userMsg);
System.out.println(userMsg);
}
out.flush();
out.close();
}
3.用token去访问需要的接口
个人对token使用的理解,
为什么用token ,不用token的两种方案
1.账号密码登陆,有第三方的风险
2.cookie session 增加了服务器的负荷
token可以代替密码,在以后访问中,都用token去访问,安全可靠,只要是安全的数据,都可以放在token 中,访问接口解析token可以拿需要的属性直接用,方便不用再查一遍。
request里面有token并且解析成功就直接访问,否则转到登陆界面