JavaWebToken
什么是Token
Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。
基于 Token 的身份验证,使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。流程是这样的
1、客户端使用用户名跟密码请求登录
2、服务端收到请求,去验证用户名与密码
3、验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
4、客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
5、客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
6、服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据
7、APP登录的时候发送加密的用户名和密码到服务器,服务器验证用户名和密码,如果成功,以某种方式比如随机生成32位的字符串作为token,存储到服务器中,并返回token到APP,以后APP请求时,
凡是需要验证的地方都要带上该token,然后服务器端验证token,成功返回所需要的结果,失败返回错误信息,让他重新登录。其中服务器上token设置一个有效期,每次APP请求的时候都验证token和有效期。
话不多说直接上代码
首先导入maven坐标,我这里用的是java-jwt
<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt --> <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.8.1</version> </dependency>
java代码拿过去即可用的,大家可以做适当的修改
package com.linje.main; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import com.auth0.jwt.JWT; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.interfaces.DecodedJWT; import com.auth0.jwt.interfaces.JWTVerifier; /** * token生成和校验 * @author ouyangjun */ public class TokenUtils { private static Map<String,String> MAP_TOKENS = new HashMap<String,String>(); private static final int VALID_TIME = 60*60*2; // token有效期(秒) private static final String TOKEN_SECRET = "zhuxiaoxiao"; public static final String TOKEN_ERROR = "F"; // 非法 public static final String TOKEN_OVERDUE = "G"; // 过期 public static final String TOKEN_FAILURE = "S"; // 失效 /** * 生成token,该token长度不一致,如需一致,可自行MD5或者其它方式加密一下 * 该方式的token只存在磁盘上,如果项目是分布式,最好用redis存储 * @param str: 该字符串可自定义,在校验token时要保持一致 * @return */ public static String getToken(String str) { String token = TokenEncryptUtils.encoded(getCurrentTime()+","+str); MAP_TOKENS.put(str, token); return token; } /** * 校验token的有效性 * @param token * @return */ public static String checkToken(String token) { if (token == null) { return TOKEN_ERROR; } try{ String[] tArr = TokenEncryptUtils.decoded(token).split(","); if (tArr.length != 2) { return TOKEN_ERROR; } // token生成时间戳 int tokenTime = Integer.parseInt(tArr[0]); // 当前时间戳 int currentTime = getCurrentTime(); if (currentTime-tokenTime < VALID_TIME) { String tokenStr = tArr[1]; String mToken = MAP_TOKENS.get(tokenStr); if (mToken == null) { return TOKEN_OVERDUE; } else if(!mToken.equals(token)) { return TOKEN_FAILURE; } return tokenStr; } else { return TOKEN_OVERDUE; } }catch (Exception e) { e.printStackTrace(); } return TOKEN_ERROR; } /**获取当前时间戳(10位整数)*/ public static int getCurrentTime() { return (int)(System.currentTimeMillis()/1000); } /** * 移除过期的token */ public static void removeInvalidToken() { int currentTime = getCurrentTime(); for (Entry<String,String> entry : MAP_TOKENS.entrySet()) { String[] tArr = TokenEncryptUtils.decoded(entry.getValue()).split(","); int tokenTime = Integer.parseInt(tArr[0]); if(currentTime-tokenTime > VALID_TIME){ MAP_TOKENS.remove(entry.getKey()); } } } /** * 测试 * @param args */ public static void main(String[] args) { String str = "username_and_password"; // 获取token String token = TokenUtils.getToken(str); System.out.println("token Result: " + token); // 校验token String checkToken = TokenUtils.checkToken(token); System.out.println("checkToken Result: " + checkToken); if(str.equals(checkToken)) { System.out.println("==>token verification succeeded!"); } } /** * * @param name 传人用名 * @param passwrod 传人密码 * @return * JWT * .withClaim 携带参数 * .withExpiresAt * .withHeader 带入头部信息 */ public static String verification(String name,String passwrod) { try { Date date = new Date(System.currentTimeMillis() + VALID_TIME); // 私用秘钥 Algorithm algorithm = Algorithm.HMAC256(passwrod); // 设置头部信息 Map<String, Object> map = new HashMap<>(); map.put("typ", "JWT"); map.put("alg", "HS256"); return JWT.create().withHeader(map) .withClaim("name", name) .withClaim("pwd", passwrod) .withExpiresAt(date) // 过期时间 .sign(algorithm); // 秘钥认证 }catch (Exception e) { return null; } } /** * 验证token是否正确 * @param token * @return */ public static boolean verify( String token) { try { Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET); JWTVerifier jwtVerifier = JWT.require(algorithm).build(); DecodedJWT jwt = jwtVerifier.verify(token); return true; } catch (Exception e) { // TODO: handle exception return true; } } }
默默地温故知新