单点登录JWT实现-实战篇

package com.dalingjia.seckill.common.utils;


import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * JWT 工具类
 */
@Component
public class JwtTokenUtil {

protected final Logger logger = LoggerFactory.getLogger(this.getClass());
public static final String AUTH_HEADER = "Authorization";
public static final String TOKEN_HEAD = "Bearer ";

private static String secret = "seckill-3600";

private Long expiration = 1*1*60*60l;//默认存储小时  3600秒

public Long getExpiration() {
    return expiration;
}

/**
 * 解析token
 * @param token
 * @return
 */
public static Claims parseToken(String token){
    Jws jws = Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token);
    Claims claims = jws.getBody();
    return claims;
}

/**
 * 创建token
 * @param claims
 * @return
 */
  public static String generateToken(Map claims) {
    return Jwts.builder()
            .setClaims(claims)
            .signWith(SignatureAlgorithm.HS512, secret)
            .compact();
  }

}

package com.dalingjia.seckill.common.interceptor;

import com.dalingjia.seckill.common.Constants;
import com.dalingjia.seckill.common.enums.ResponseCodeEnum;
import com.dalingjia.seckill.common.exceptions.ValidateException;
import com.dalingjia.seckill.common.utils.CommonUtil;
import com.dalingjia.seckill.common.utils.JwtTokenUtil;
import com.dalingjia.seckill.entity.response.CheckAuthResponse;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.SignatureException;
import lombok.extern.log4j.Log4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created by ytw83 on 2019/1/1.
 */
@Log4j
public class LoginInterceptor extends HandlerInterceptorAdapter{
private static String SUCCESS = "000000";

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    String authHeader = request.getHeader(JwtTokenUtil.AUTH_HEADER);
    boolean isAjax = CommonUtil.isAjax(request);
    if (StringUtils.isEmpty(authHeader)) {
        return response(isAjax,response);
    }
    String accessToken = authHeader.substring(JwtTokenUtil.TOKEN_HEAD.length());
    if (StringUtils.isEmpty(accessToken)) {
        return response(isAjax,response);
    }

    CheckAuthResponse checkAuthResponse = validToken(accessToken);
    if (SUCCESS.equals(checkAuthResponse.getCode())) {
        return super.preHandle(request, response, handler);
    }

    if (isAjax) {
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().write("{\"code\":\""+checkAuthResponse.getCode()+"\"" +
                ",\"msg\":\""+checkAuthResponse.getMsg()+"\"}");
        return false;
    }
    response.sendRedirect(Constants.SSO_ACCESS_URL);
    return false;
}


public CheckAuthResponse validToken(String token) {
    CheckAuthResponse response=new CheckAuthResponse();
    try{
        beforeValidateAuth(token);

        Claims claims=JwtTokenUtil.parseToken(token);
        response.setUid(claims.get("uid").toString());
        response.setCode(ResponseCodeEnum.SUCCESS.getCode());
        response.setMsg(ResponseCodeEnum.SUCCESS.getMsg());

    }catch (ExpiredJwtException e){
        log.error("ExpiredJwtException :"+e);
        response.setCode(ResponseCodeEnum.TOKEN_EXPIRE.getCode());
        response.setMsg(ResponseCodeEnum.TOKEN_EXPIRE.getMsg());
    }catch (SignatureException e1){
        log.error("SignatureException :"+e1);
        response.setCode(ResponseCodeEnum.SIGNATURE_ERROR.getCode());
        response.setMsg(ResponseCodeEnum.SIGNATURE_ERROR.getMsg());
    }catch (Exception e){
        log.error("login occur exception :"+e);
        response.setCode(ResponseCodeEnum.SYSTEM_BUSY.getCode());
        response.setMsg(ResponseCodeEnum.SYSTEM_BUSY.getMsg());
    }finally {
        log.info("response:"+response);
    }

    return response;
}

private void beforeValidateAuth(String token){
    if(StringUtils.isEmpty(token)){
        throw new ValidateException("token信息为空");
    }
}

 private boolean response(boolean isAjax,HttpServletResponse response) throws IOException {
    if(isAjax){
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().write("{\"code\":\"-1\",\"msg\":\"error\"}");
        return false;
    }
    response.sendRedirect(Constants.SSO_ACCESS_URL);
    return false;
 }
}



package com.dalingjia.seckill.common.exceptions;

import com.dalingjia.seckill.common.enums.ResponseCodeEnum;

public class ValidateException extends RuntimeException {

/**
 * versionId
 */
private static final long serialVersionUID = 7172827201346602909L;


/**
 * 返回码
 */
private String errorCode;
/**
 * 信息
 */
private String errorMessage;

/**
 * 构造函数
 */
public ValidateException() {
    super();
}

/**
 * 构造函数
 *
 * @param errorCode
 */
public ValidateException(String errorCode) {
    super(errorCode);
    this.errorCode= ResponseCodeEnum.SYS_PARAM_NOT_RIGHT.getCode();
    this.errorMessage= ResponseCodeEnum.SYS_PARAM_NOT_RIGHT.getMsg();
}

/**
 * 构造函数
 *
 * @param cause
 */
public ValidateException(Throwable cause) {
    super(cause);
}

/**
 * 构造函数
 *
 * @param errorCode
 * @param cause
 */
public ValidateException(String errorCode, Throwable cause) {
    super(cause);
    this.errorCode = errorCode;
}

/**
 * 构造函数
 *
 * @param errorCode
 * @param message
 */
public ValidateException(String errorCode, String message) {
    super();
    this.errorCode = errorCode;
    this.errorMessage = message;
}

/**
 * 构造函数
 *
 * @param errorCode
 * @param message
 * @param cause
 */
public ValidateException(String errorCode, String message, Throwable cause) {
    super(cause);
    this.errorCode = errorCode;
    this.errorMessage = message;
}

/**
 * Getter method for property errorCode.
 *
 * @return property value of errorCode
 */
public String getErrorCode() {
    return errorCode;
}

/**
 * Setter method for property errorCode.
 *
 * @param errorCode value to be assigned to property errorCode
 */
public void setErrorCode(String errorCode) {
    this.errorCode = errorCode;
}

/**
 * Getter method for property errorMessage.
 *
 * @return property value of errorMessage
 */
public String getErrorMessage() {
    return errorMessage;
}

/**
 * Setter method for property errorMessage.
 *
 * @param errorMessage value to be assigned to property errorMessage
 */
 public void setErrorMessage(String errorMessage) {
    this.errorMessage = errorMessage;
 }

}




package com.dalingjia.seckill.common.enums;


public enum  ResponseCodeEnum {
  USERORPASSWORD_ERRROR("001001","用户名或密码不存在"),
  SUCCESS("000000","成功"),
  SYS_PARAM_NOT_RIGHT("001002","请求参数错误"),
  TOKEN_EXPIRE("001003","token过期"),
  SIGNATURE_ERROR("001004","签名验证失败"),
  QUERY_DATA_NOT_EXIST("001005","请求数据不存在"),
  SYSTEM_BUSY("001099","系统繁忙,请稍候重试");

private final String code;
private final  String msg;

ResponseCodeEnum(String code, String msg) {
    this.code = code;
    this.msg = msg;
}

public String getCode() {
    return code;
}

public String getMsg() {
    return msg;
 }
}




package com.dalingjia.seckill.common.utils;

import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;

/**
 * Created by ytw83 on 2019/1/1.
 */
 public class CommonUtil {
  public static boolean isAjax(HttpServletRequest request){
    boolean isAjaxRequest = false;
    if(!StringUtils.isBlank(request.getHeader("x-requested-with")) && request.getHeader("x-requested-with").equals("XMLHttpRequest")){
        isAjaxRequest = true;
    }
    return isAjaxRequest;
 }
}




package com.dalingjia.seckill.entity.response;

import lombok.Data;

import java.io.Serializable;

@Data
public class CheckAuthResponse implements Serializable {
  private static final long serialVersionUID = -3294145027267783959L;
  private String code;
  private String msg;
  private String uid;

 @Override
 public String toString() {
    return "CheckAuthResponse{" +
            "uid='" + uid + '\'' +
            "} " + super.toString();
 }
}

你可能感兴趣的:(单点登录JWT实现-实战篇)