Api接口冪等設計


1,Api接口冪等設計,也就是要保證數據的唯一性,不允許有重復。

     例如:rpc 遠程調用,因為網絡延遲,出現了調用了2次的情況。

                表單連續點擊,出現了重復提交。

                接口暴露之后,會被模擬請求工具(Jemter等)進行攻擊。

2,怎么樣保證接口冪等設計呢?

      可以使用Token方式,每次調用Api 接口(提交表單)之前,會調用api生成token,並將token給客戶端保存,redis里面也保存token,redis 可以設置有效時長,約15-60 分鍾

      當提交表單的時候,請求頭里面要攜帶token,將請求頭里面的token 拿出來和redis 里面的token進行比較,redis 里面有token,則表單提交,同時,刪除token,redis 里面沒有,則表單不提交。

3,調用index 方法的時候,生成token,客戶端保存,點擊提交,調用postIndex 接口前,token 驗證

4,安裝redis

5, 基於redis 寫個redis 緩存token

package com.aiyuesheng.util;

import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

@Component
public class BaseRedisService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    public void setString(String key, Object data, Long timeout) {
        if (data instanceof String) {
            String value = (String) data;
            stringRedisTemplate.opsForValue().set(key, value);
        }
        if (timeout != null) {
            stringRedisTemplate.expire(key, timeout, TimeUnit.SECONDS);
        }
    }

    public Object getString(String key) {
        return stringRedisTemplate.opsForValue().get(key);
    }

    public void delKey(String key) {
        stringRedisTemplate.delete(key);
    }

}

 

package com.aiyuesheng.util;

import java.util.UUID;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class RedisToken {
    @Autowired
    private BaseRedisService baseRedisService;

    private static final long TIMEOUT = (60 * 60 * 60);

    public String setToken() {
        String token = System.currentTimeMillis() + "" + UUID.randomUUID();
        baseRedisService.setString(token, token, TIMEOUT);
        return token;
    }

    public String getToken(String tokenKey) {
        if(!StringUtils.isEmpty((String) baseRedisService.getString(tokenKey))){
            return (String) baseRedisService.getString(tokenKey);
        }
        return "";
    }
}

6,每次進行對比下。。。驗證

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM