jwt json token 和 跨域访问

来源:互联网 发布:计算机动画算法与技术 编辑:程序博客网 时间:2024/06/06 01:18

引入jar包:

// https://mvnrepository.com/artifact/com.thetransactioncompany/cors-filter    compile group: 'com.thetransactioncompany', name: 'cors-filter', version: '2.2.1'// https://mvnrepository.com/artifact/com.thetransactioncompany/java-property-utils    compile group: 'com.thetransactioncompany', name: 'java-property-utils', version: '1.9.1'    // https://mvnrepository.com/artifact/com.nimbusds/nimbus-jose-jwt    compile group: 'com.nimbusds', name: 'nimbus-jose-jwt', version: '4.13.1'

处理跨域:

/** * 服务端跨域处理过滤器,该过滤器需要依赖cors-filter-2.2.1.jar和java-property-utils-1.9.1.jar * @author running@vip.163.com * */@WebFilter(urlPatterns={"/*"},asyncSupported=true,        initParams={                @WebInitParam(name="cors.allowOrigin",value="*"),                @WebInitParam(name="cors.supportedMethods",value="CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, TRACE"),                @WebInitParam(name="cors.supportedHeaders",value="token,Accept, Origin, X-Requested-With, Content-Type, Last-Modified"),//注意,如果token字段放在请求头传到后端,这里需要配置                @WebInitParam(name="cors.exposedHeaders",value="Set-Cookie"),                @WebInitParam(name="cors.supportsCredentials",value="true")        })public class WebCorsFilter extends CORSFilter implements javax.servlet.Filter {    public void init(FilterConfig config) throws ServletException {        System.out.println("跨域资源处理过滤器初始化了");        super.init(config);    }    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {        System.out.println("跨域过滤器");        super.doFilter(request, response, chain);    }    public void setConfiguration(CORSConfiguration config) {        super.setConfiguration(config);    }}

定义枚举:

package com.shop.utils.JwtUtils;/** * 枚举,定义token的三种状态 * @author running@vip.163.com * */ public enum TokenState {     /**      * 过期      */    EXPIRED("EXPIRED"),    /**     * 无效(token不合法)     */    INVALID("INVALID"),    /**     * 有效的     */    VALID("VALID");    private String  state;    private TokenState(String state) {        this.state = state;    }    /**     * 根据状态字符串获取token状态枚举对象     * @param tokenState     * @return     */    public static TokenState getTokenState(String tokenState){        TokenState[] states=TokenState.values();        TokenState ts=null;        for (TokenState state : states) {            if(state.toString().equals(tokenState)){                ts=state;                break;            }        }        return ts;    }    public String toString() {        return this.state;    }    public String getState() {        return state;    }    public void setState(String state) {        this.state = state;    }}

定义jwt工具:

package com.shop.utils.JwtUtils;/** * @author 阳十三 * @email wdful165177@gmail.com * @blog http://www.item1024.com * @date 2017/9/5 */import com.nimbusds.jose.*;import com.nimbusds.jose.crypto.MACSigner;import com.nimbusds.jose.crypto.MACVerifier;import net.minidev.json.JSONObject;import java.util.Date;import java.util.HashMap;import java.util.Map;public class JwtUtil {    /**     * 秘钥     */    private static final byte[] SECRET="diiwneuqeu1231231kiowejfi2".getBytes();    /**     * 初始化head部分的数据为     * {     *      "alg":"HS256",     *      "type":"JWT"     * }     */    private static final JWSHeader header=new JWSHeader(JWSAlgorithm.HS256, JOSEObjectType.JWT, null, null, null, null, null, null, null, null, null, null, null);    /**     * 生成token,该方法只在用户登录成功后调用     *     * @param payload,可以存储用户id,token生成时间,token过期时间等自定义字段     * @return token字符串,若失败则返回null     */    public static String createToken(Map<String, Object> payload) {        payload.put("ext",new Date().getTime()+1000*60*60*5);        payload.put("sign",0);        String tokenString=null;        // 创建一个 JWS object        JWSObject jwsObject = new JWSObject(header, new Payload(new JSONObject(payload)));        try {            // 将jwsObject 进行HMAC签名            jwsObject.sign(new MACSigner(SECRET));            tokenString=jwsObject.serialize();        } catch (JOSEException e) {            System.err.println("签名失败:" + e.getMessage());            e.printStackTrace();        }        return tokenString;    }    /**     * 校验token是否合法,返回Map集合,集合中主要包含    state状态码   data鉴权成功后从token中提取的数据     * 该方法在过滤器中调用,每次请求API时都校验     * @param token     * @return  Map<String, Object>     */    public static Map<String, Object> validToken(String token) {        Map<String, Object> resultMap = new HashMap<String, Object>();        try {            JWSObject jwsObject = JWSObject.parse(token);            Payload payload = jwsObject.getPayload();            JWSVerifier verifier = new MACVerifier(SECRET);            if (jwsObject.verify(verifier)) {                JSONObject jsonOBj = payload.toJSONObject();                // token校验成功(此时没有校验是否过期)                resultMap.put("state", TokenState.VALID.toString());                // 若payload包含ext字段,则校验是否过期                if (jsonOBj.containsKey("ext")) {                    long extTime = Long.valueOf(jsonOBj.get("ext").toString());                    long curTime = new Date().getTime();                    // 过期了                    if (curTime > extTime) {                        resultMap.clear();                        resultMap.put("state", TokenState.EXPIRED.toString());                    }                }                resultMap.put("data", jsonOBj);            } else {                // 校验失败                resultMap.put("state", TokenState.INVALID.toString());            }        } catch (Exception e) {            //e.printStackTrace();            // token格式不合法导致的异常            resultMap.clear();            resultMap.put("state", TokenState.INVALID.toString());        }        return resultMap;    }}

控制器操作 登陆成功后生成token

 //生成token                Map<String , Object> payload=new HashMap<String, Object>();                payload.put("user_id",userInfo.getUserId());                String token = JwtUtil.createToken(payload);                Map map = new HashMap();                map.put("msg","登陆成功");                map.put("token",token); ```# 定义拦截器  拦截需要用户权限的路由  检验token

package com.shop.interceptor;

import java.io.PrintWriter;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.gson.Gson;
import com.shop.utils.JwtUtils.JwtUtil;
import com.shop.utils.JwtUtils.TokenState;
import com.shop.utils.ResultWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class LoginInterceptor implements HandlerInterceptor{

@Autowiredprivate RedisTemplate<String,String> redisTemplate;public void afterCompletion(HttpServletRequest request,                            HttpServletResponse response, Object handler, Exception arg3)        throws Exception {}public void postHandle(HttpServletRequest request, HttpServletResponse response,                       Object handler, ModelAndView model) throws Exception {}public boolean preHandle(HttpServletRequest request, HttpServletResponse response,                         Object handler) throws Exception {    System.out.println(request.getRequestURL());    response.setCharacterEncoding("utf-8");    String token = request.getHeader("token");    //token不存在    if (null != token && !token.equals(" ")) {        Map<String, Object> resultMap = JwtUtil.validToken(token);        TokenState state = TokenState.getTokenState((String) resultMap.get("state"));        switch (state) {            case VALID:                //取出payload中数据,放入到request作用域中                request.setAttribute("data", resultMap.get("data"));                //放行                return true;            case EXPIRED:            case INVALID:                default:                System.out.println("无效token");                responseMessage(response, response.getWriter(), new ResultWrapper<>().ErrorWithData("登陆已过期 请重新登录"));                return false;        }    } else {        System.out.println("token = null");        responseMessage(response, response.getWriter(), new ResultWrapper<>().ErrorWithData("您还未登陆"));

// response.sendRedirect(“/login_register.py”);
return false;
}
}

//请求不通过,返回错误信息给客户端private void responseMessage(HttpServletResponse response, PrintWriter out, ResultWrapper resultWrapper) {    response.setContentType("application/json; charset=utf-8");    String json = new Gson().toJson(response);    out.print(json);    out.flush();    out.close();}

}

“`