栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

传参统一jwt加密(坑)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

传参统一jwt加密(坑)

说明

这个涉及到的主要是和前端约定加密方式,我这边主动采用了jwt方式,原因吗就不解释了。

实现起来大致思想就是做拦截,之前尝试了一版注解方式,做了一半想到一个问题。。注解拦截的参数是已经绑定之后的了。。要是自己再去处理的话就会非常麻烦。。

后来果断放弃,想了想还是使用过滤方便,想着只要把请求参数改了不就行了,实际上这样确实是可行的,就是有个坑,得同时修改getParamNames方法,不然参数是绑定不了的

先说实现吧 定义一个过滤器
package com.fedtech.common.filter.jwt;

import org.springframework.stereotype.Component;

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


@Component
public class JwtFilter implements Filter {

    @Override
    public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
     throws IOException, ServletException {
 ParameterRequestWrapper paramsRequest = new ParameterRequestWrapper((HttpServletRequest) arg0);
 String[] secretParams = paramsRequest.getParameterMap().get("secretParam");
 if (secretParams == null) {
     arg2.doFilter(arg0, arg1);
 } else {
     arg2.doFilter(paramsRequest, arg1);
 }
    }

    @Override
    public void init(FilterConfig arg0) {

    }

    @Override
    public void destroy() {

    }
}


重写获取参数相关的方法
package com.fedtech.common.filter.jwt;

import com.alibaba.fastjson.JSON;
import com.fedtech.common.util.StringJsonUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.util.WebUtils;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;

import static com.fedtech.common.constants.Request.RequestConstants.CONTENT_TYPE;
import static org.apache.commons.lang3.StringUtils.equalsAny;
import static org.apache.commons.lang3.StringUtils.isNotBlank;


@Slf4j
public class ParameterRequestWrapper extends HttpServletRequestWrapper {

    
    private final Map params = new HashMap<>();


    
    public ParameterRequestWrapper(HttpServletRequest request) {
 // 将request交给父类,以便于调用对应方法的时候,将其输出,其实父亲类的实现方式和第一种new的方式类似
 super(request);
 //将参数表,赋予给当前的Map以便于持有request中的参数
 Map requestMap = new HashMap<>(request.getParameterMap());
 //这边拿到和前端约定的参数名
 String[] secretParams = requestMap.get("secretParam");
 if (secretParams == null) {
     return;
 }
 String secretParam = secretParams[0];
 //没有加密参数的话就不处理了
 if (isNotBlank(secretParam)) {
     //jwt解析一波
     Jws jws = Jwts.parser()
      .setSigningKey("secret".getBytes(StandardCharsets.UTF_8))
      .parseClaimsJws(secretParam);
     //这边只要过滤掉几个不需要的参数就行啦啦啦啦!!!!
     jws.getBody().forEach((x, y) -> {
  if (!equalsAny(x, "sub", "exp", "lat", "jti", "iat")) {
      requestMap.put(x, new String[]{String.valueOf(y)});
  }
     });
 }
 //在这边全部存起来哈!!
 this.params.putAll(requestMap);
 //这个是div的,去除前后空格
 this.modifyParameterValues();
    }

    
    @Override
    public ServletInputStream getInputStream() throws IOException {
 //非json类型,直接返回
 if (!super.getHeader(CONTENT_TYPE).equalsIgnoreCase("json")) {
     return super.getInputStream();
 }
 //为空,直接返回
 String json = IOUtils.toString(super.getInputStream(), StandardCharsets.UTF_8);
 if (StringUtils.isEmpty(json)) {
     return super.getInputStream();
 }
 log.info("转化前参数:{}", json);
 Map map = StringJsonUtils.jsonStringToMap(json);
 log.info("转化后参数:{}", JSON.toJSONString(map));
 ByteArrayInputStream bis = new ByteArrayInputStream(JSON.toJSONString(map).getBytes(StandardCharsets.UTF_8));
 return new MyServletInputStream(bis);
    }

    
    private void modifyParameterValues() {
 Set set = params.keySet();
 for (String key : set) {
     String[] values = params.get(key);
     String[] newValues = new String[values.length];
     for (int i = 0; i < values.length; i++) {
  newValues[i] = values[i].trim();
  if (newValues[i].length() <= 0) {
      newValues[i] = null;
  }
     }
     params.put(key, newValues);
 }
    }

    
    @Override
    public Enumeration getParameterNames() {
 Vector vector = new Vector<>(params.keySet());
 return vector.elements();
    }

    
    @Override
    public String getParameter(String name) {
 String[] values = params.get(name);
 if (values == null || values.length == 0) {
     return null;
 }
 return values[0];
    }

    
    @Override
    public String[] getParameterValues(String name) {//同上
 return params.get(name);
    }

    static class MyServletInputStream extends ServletInputStream {
 private final ByteArrayInputStream bis;

 public MyServletInputStream(ByteArrayInputStream bis) {
     this.bis = bis;
 }

 @Override
 public boolean isFinished() {
     return true;
 }

 @Override
 public boolean isReady() {
     return true;
 }

 @Override
 public void setReadListener(ReadListener listener) {

 }

 @Override
 public int read() {
     return bis.read();
 }
    }
}


Debug最后找到获取参数的地方,这个方法是必须重写的,不然绑定的时候是拿不到的

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号