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<Claims> jws = Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token);
Claims claims = jws.getBody();
return claims;
}
/**
* 创建token
* @param claims
* @return
*/
public static String generateToken(Map<String, Object> 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 <tt>errorCode</tt>.
*
* @return property value of errorCode
*/
public String getErrorCode() {
return errorCode;
}
/**
* Setter method for property <tt>errorCode</tt>.
*
* @param errorCode value to be assigned to property errorCode
*/
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
/**
* Getter method for property <tt>errorMessage</tt>.
*
* @return property value of errorMessage
*/
public String getErrorMessage() {
return errorMessage;
}
/**
* Setter method for property <tt>errorMessage</tt>.
*
* @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实现-实战篇
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- http://lion1ou.win/2017/01/18/ 使用json-web-token 第三方模块:dja...
- 在分布式环境中,如何支持PC、APP(ios、android)等多端的会话共享,这也是所有公司都需要的解决方案,用...
- 在分布式环境中,如何支持PC、APP(ios、android)等多端的会话共享,这也是所有公司都需要的解决方案,用...
- 单点登录(英语:Single sign-on,缩写为 SSO),又译为单一签入,一种对于许多相互关连,但是又是各自...