天天看点

php jwt单点登录,单点登录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.*;

@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;

}

public static Claims parseToken(String token){

Jws jws = Jwts.parser()

.setSigningKey(secret)

.parseClaimsJws(token);

Claims claims = jws.getBody();

return claims;

}

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;

@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 {

private static final long serialVersionUID = 7172827201346602909L;

private String errorCode;

private String errorMessage;

public ValidateException() {

super();

}

public ValidateException(String errorCode) {

super(errorCode);

this.errorCode= ResponseCodeEnum.SYS_PARAM_NOT_RIGHT.getCode();

this.errorMessage= ResponseCodeEnum.SYS_PARAM_NOT_RIGHT.getMsg();

}

public ValidateException(Throwable cause) {

super(cause);

}

public ValidateException(String errorCode, Throwable cause) {

super(cause);

this.errorCode = errorCode;

}

public ValidateException(String errorCode, String message) {

super();

this.errorCode = errorCode;

this.errorMessage = message;

}

public ValidateException(String errorCode, String message, Throwable cause) {

super(cause);

this.errorCode = errorCode;

this.errorMessage = message;

}

public String getErrorCode() {

return errorCode;

}

public void setErrorCode(String errorCode) {

this.errorCode = errorCode;

}

public String getErrorMessage() {

return 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;

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();

}

}