前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用aop加解密http接口

使用aop加解密http接口

原创
作者头像
Java旅途
修改2020-06-28 10:21:05
8140
修改2020-06-28 10:21:05
举报
文章被收录于专栏:Java旅途

背景

最近在写一个小程序接口,由于安全性比较高,因此需要给请求参数和响应进行加密处理。如果在每个方法上都加密解密,那样代码就显得太繁琐了而且工作量会加大。所以,我们会统一进行加解密处理,一种比较传统的方式就是通过拦截器进行拦截处理。在这里我们选择通过使用spring的aop来实现。

处理方案

1.比较spring的五种通知后。很容易发现,环绕通知可以解决我们的问题,环绕通知有哪些特点呢?

  • 环绕通知是所有通知类型中功能最为强大的, 能够全面地控制连接点. 甚至可以控制是否执行连接点 。
  • 对于环绕通知来说, 连接点的参数类型必须是 ProceedingJoinPoint. 它是 JoinPoint的子接口, 允许控制何时执行, 是否执行连接点 。
  • 在环绕通知中需要明确调用 ProceedingJoinPoint 的 proceed() 方法来执行被代理的方法. 如果忘记这样做就会导致通知被执行了, 但目标方法没有被执行 。
  • 环绕通知的方法需要返回目标方法执行之后的结果, 即调用 joinPoint.proceed(); 的返回值, 否则会出现空指针异常

2.具体看一下代码如何实现。

  • aspect类
代码语言:txt
复制
import com.legendnet.elecmeter.utils.EncryptUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * @Author 情系IT
 * @Description
 * @Date 2019-12-04 14:55
 */
@Aspect
@Slf4j
@Component
public class HttpAspect {

    // 定义切点controller包及子包下面的所有方法
    @Pointcut("execution(public * com.legendnet.elecmeter.controller..*.*(..))")
    public void httpRequest(){}

    @Around("httpRequest()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Exception {

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        // target 判断来源然后根据不同的解密算法解密
        String target = request.getParameter("target");
        String paramCode = request.getParameter("param_code");
        paramCode = paramCode.replaceAll(" ", " ");

        if(StringUtils.isNotBlank(paramCode)){
            if("miniProgram".equals(target)){
                paramCode = EncryptUtils.aesDecrypt(paramCode);
            }

            log.info("请求参数为:【{}】",paramCode);
        }
		request.setAttribute("param_code",paramCode);
        Object proceed = "";
        try {
            proceed = proceedingJoinPoint.proceed();
            if("miniProgram".equals(target)){
            	proceed = EncryptUtils.aesEncrypt(proceed.toString());
            }
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return proceed;
    }
}
  • controller类
代码语言:txt
复制
import com.alibaba.fastjson.JSON;
import com.legendnet.elecmeter.common.ResultBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author 情系IT
 * @Description
 * @Date 2019-12-04 15:23
 */
@RestController
@Slf4j
public class TestController {

    @RequestMapping("test")
    public String test(HttpServletRequest request){
        String param_code = request.getAttribute("param_code").toString();
        log.info("我已接收到参数,参数为:【{}】",paramCode);

        ResultBean resultBean = new ResultBean();
        resultBean.fillData("这就是我的响应");
        return JSON.toJSONString(resultBean);
    }
}

3.由于小程序和app的加密方式不同,为了代码的高可用,我们通过target参数来判断其来源,然后选择不同的加解密方式进行处理。

大功告成,接下来安心的写接口就可以了,妈妈再也不用担心我去处理加密解密的问题了。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 处理方案
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档