安全技术--接口幂等性设计

作者: 迦叶_金色的人生_荣耀而又辉煌 | 来源:发表于2020-11-22 09:19 被阅读0次

    上一篇 <<<安全技术--Https相关知识
    下一篇 >>>安全框架--SpringSecurity


    幂等:无论请求多少次,数据都不会变,防止重复提交

    幂等设计方案

    • 1.MVCC方案(乐观锁方式)

    select * from tablename where condition=#condition# // 取出要跟新的对象,带有版本 versoin
    update tableName set name=#name#,version=version+1 where version=#version#
    在更新的过程中利用 version 来防止,其他操作对对象的并发更新,导致更新丢失。为了避免失败,通常需要一定的重试机制。

    • 2.悲观锁

    select for update,整个执行过程中锁定该订单对应的记录。注意:这种在DB读大于写的情况下尽量少用。

    • 3.去重表

    在插入数据的时候,插入去重表,利用数据库的唯一索引特性,保证唯一的逻辑。

    • 4.Token机制

    业务要求:页面的数据只能被点击提交一次
    发生原因:由于重复点击或者网络重发,或者 nginx 重发等情况会导致数据被重复提交
    解决办法:
    集群环境:采用token加redis(redis 单线程的,处理需要排队)
    单JVM环境:采用token加redis或token加jvm内存
    处理流程:
    --数据提交前要向服务的申请token,token放到redis或jvm内存,token有有效时间
    --提交后后台校验token,同时删除token
    token特点:要申请,一次有效性,可以限流

    纯手写互联网API接口幂等框架

      1. 接口方式保证幂等性

    a、提供查询令牌查询接口
    b、令牌放在请求头中提交,服务端使用AOP统一处理

      1. 表单提交保证幂等性

    a、自定义注解ExtApiToken,AOP中发现此注解就生成令牌信息放到request中,页面上做令牌的隐藏
    b、-令牌信息和其他数据一起以form方式提交到服务端,服务端以ExtApiIdempotent注解来做AOP统一处理

    • 3.核心代码
    // 1.使用AOP环绕通知拦截所有访问(controller)
    @Pointcut("execution(public * com.jarye.controller.*.*(..))")
    public void rlAop() {}
    
    // 含有ExtApiToken注解的均设置令牌信息
    @Before("rlAop()")
    public void before(JoinPoint point) {
        MethodSignature signature = (MethodSignature) point.getSignature();
        ExtApiToken extApiToken = signature.getMethod().getDeclaredAnnotation(ExtApiToken.class);
        if (null==extApiToken) {
            return;
        }
        // 可以放入到AOP代码 前置通知
        getRequest().setAttribute("token", redisToken.getToken());
    }
    
    // 环绕通知
    @Around("rlAop()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        // 2.判断方法上是否有加ExtApiIdempotent注解
        MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
        ExtApiIdempotent declaredAnnotation = methodSignature.getMethod().getDeclaredAnnotation(ExtApiIdempotent.class);
        // 3.如何方法上有加上ExtApiIdempotent
        if (declaredAnnotation != null) {
            String type = declaredAnnotation.type();
            // 如何使用Token 解决幂等性
            String token = null;
            HttpServletRequest request = getRequest();
            //接口形式是放在头部,表单形式是放在body中
            if (type.equals(ConstantUtils.EXTAPIHEAD)) {
                token = request.getHeader("token");
            } else {
                token = request.getParameter("token");
            }
            if (StringUtils.isEmpty(token)) {
                return "参数错误";
            }
            // 3.接口获取对应的令牌,如果能够获取该(从redis获取令牌)令牌(将当前令牌删除掉) 就直接执行该访问的业务逻辑
            boolean isToken = redisToken.findToken(token);
            // 4.接口获取对应的令牌,如果获取不到该令牌 直接返回请勿重复提交
            if (!isToken) {
                response("请勿重复提交!");
                // 后面方法不在继续执行
                return null;
            }
    
        }
        // 放行
        Object proceed = proceedingJoinPoint.proceed();
        return proceed;
        
    }
    

    相关文章链接:
    <<<Web常用攻击手段-XSS
    <<<Web常用攻击手段-SQL注入
    <<<Web常用攻击手段-Http请求防盗链
    <<<Web常用攻击手段-CSRF攻击
    <<<Web常用攻击手段-上传文件漏洞
    <<<Web常用攻击手段-忘记密码
    <<<Web常用攻击手段-其他漏洞
    <<<安全技术--数据加密/认证技术
    <<<安全技术--Https相关知识
    <<<安全框架--SpringSecurity
    <<<安全框架--JWT
    <<<安全框架--OAuth2
    <<<安全架构整体设计方案

    相关文章

      网友评论

        本文标题:安全技术--接口幂等性设计

        本文链接:https://www.haomeiwen.com/subject/rswliktx.html