使用jwt和攔截器來實現登錄接口

使用jwt來創建token和解密token,攔截器則是用來校驗token。

jwt生成token

/**
 * @author weiqi:
 * @version 創建時間:2018年11月5日 下午9:23:01 登錄Token的生成和解析
 */
public class JwtUtils {
	
	private static Logger log = LoggerFactory.getLogger(JwtUtils.class);  
	
	/** token祕鑰,請勿泄露,請勿隨便修改  */
	public static final String SECRET = GeneralCode.TOKEN_SECRET;
	/** token 過期時間: 10天 */
	public static final int calendarField = Calendar.DATE;
	public static final int calendarInterval = GeneralCode.TOKEN_OUT_OF_DATE;

	/**
	 * JWT生成Token.<br/>
	 * 
	 * JWT構成: header, payload, signature
	 * 
	 * @param user_id
	 *            登錄成功後用戶user_id, 參數user_id不可傳空
	 */
	public static String createToken(Long user_id) throws Exception {
		log.info("create token...");
		Date iatDate = new Date();
		// expire time
		Calendar nowTime = Calendar.getInstance();
		nowTime.add(calendarField, calendarInterval);
		Date expiresDate = nowTime.getTime();
		// header Map
		Map<String, Object> map = new HashMap<>();
		map.put("alg", "HS256");
		map.put("typ", "JWT");
		// build token
		// param backups {iss:Service, aud:APP}
		String token = JWT.create().withHeader(map) // header
				.withClaim("iss", "Service") // payload
				.withClaim("aud", "APP").withClaim("user_id", null == user_id ? null : user_id.toString())
				.withIssuedAt(iatDate) // sign time
				.withExpiresAt(expiresDate) // expire time
				.sign(Algorithm.HMAC256(SECRET)); // signature
		return token;
	}

	/**
	 * 解密Token
	 * 
	 * @param token
	 * @return
	 * @throws Exception
	 */

	public static Map<String, Claim> verifyToken(String token) throws Exception{
		DecodedJWT jwt = null;
		log.info("start identify token...");
		JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
		jwt = verifier.verify(token);
		
		return jwt.getClaims();

	}

	/**
	 * 根據Token獲取user_id
	 * 
	 * @param token
	 * @return user_id
	 */

	public static Long getUID(String token) throws Exception{
		Map<String, Claim> claims = verifyToken(token);
		Claim user_id_claim = claims.get("user_id");
		if (null == user_id_claim || StringUtils.isEmpty(user_id_claim.asString())) {
			return 0L;
		}
		log.info("get userid " + Long.valueOf(user_id_claim.asString()));
		return Long.valueOf(user_id_claim.asString());
	}
}

 在登錄時創建並給前端返回token

        customerRepository.insertLoginInfo(LoginInfoModel);//插入登錄信息
		String token = "";
		try {
			token = JwtUtils.createToken(userid);//生成token
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		customerInfoDto.setCustomerModel(customerModel);
		customerInfoDto.setToken(token);

前端調用接口時使用攔截器攔截

public class LoginInterceptor implements HandlerInterceptor {
	private static String[] IGNORE_URI = {"/login/login"};
	private static Logger log = LoggerFactory.getLogger(HandlerInterceptor.class);  
	/**
	 * 進入controller層之前攔截請求
	 * @param httpServletRequest
	 * @param httpServletResponse
	 * @param o
	 * @return
	 * @throws Exception
	 */
	@Override
	public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
		System.out.println("---------------------開始進入請求地址攔截----------------------------");
		boolean flag = false;
        String url = httpServletRequest.getRequestURL().toString();
        
		for (String s : IGNORE_URI) {
            if (url.contains(s)) {
                flag = true;
                break;
            }
        }
        if (!flag) {
			String token = httpServletRequest.getHeader("Authorization");
			if(!"".equals(token)||!token.isEmpty()) {
				try {
					JwtUtils.getUID(token);
				}catch(Exception e) {
					log.error("token失效,當前url:" + url);
					e.printStackTrace();
					httpServletResponse.setHeader("tokenstatus", "timeout");//在響應頭設置token狀態  
					httpServletResponse.setCharacterEncoding("text/html;charset=utf-8");
					httpServletResponse.setContentType("text/html;charset=utf-8");
					httpServletResponse.getWriter().print("this token is time out");
					return false;
				}
			}else {
				
			}
        }
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
		System.out.println("--------------處理請求完成後視圖渲染之前的處理操作---------------");
	}

	@Override
	public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
		System.out.println("---------------視圖渲染之後的操作-------------------------");
	}
}

添加到啓動配置中

@Configuration
public class WebAppConfig implements WebMvcConfigurer {
	@Override
	public void addInterceptors(InterceptorRegistry registry){
		//註冊自定義攔截器,添加攔截路徑和排除攔截路徑
		registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/login/**");//攔截除登錄以外的其他接口
	}
}

這樣就完成了,每次獲取數據時都需要在請求頭中帶上token,不然就會提示獲取失敗

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章