精华内容
下载资源
问答
  • 给调用者一个SECRET,每次调用者需要调用接口的时候,都需要把这个SECRET带过来(为了安全需要对key进行一系列加密的措施)一个SECRET就代表一个调用者,把相应的SECRET的调用次数放入缓存中(必须确保次数增加的原子)...

    如何限制接口调用者对接口的调用频率?

    问题:对某个对外暴露的接口加一个限制:调用者一分钟之内调用次数不能超过100次,如果超过100次就直接返回给调用者失败的信息。

    给调用者一个SECRET,每次调用者需要调用接口的时候,都需要把这个SECRET带过来(为了安全需要对key进行一系列加密的措施)

    一个SECRET就代表一个调用者,把相应的SECRET的调用次数放入缓存中(必须确保次数增加的原子性),并且把SECRET当做缓存的SECRET(这里如果区分方法的话,可以把方法和KEY做一次加密)。

    这里主要的难点就是,如何判断调用者1分钟之内调用次数是否超过100?也就是很难确实这个1分钟的开始时间。

    我现在的想法是:分别把当前秒调用的次数存入缓存。比如说,当前调用者调用次数为3,那么我就往缓存中加入KEY=SECRET_1,VALUE=3;然后调用者在第二秒调用的次数为4,那么就往缓存中加入KEY=SECRET_2,VALUE=3;如此循环,当循环到61秒的时候替换KEY=SECRET_1中得VAALUE,每次调用的时候计算SECRET_1~SECRET_60的值来判断调用次数,是否超过100次。(这里具体一秒钟调用几次,需要通过时间戳来算出是第几秒。这里以60秒为时间周期,并且以秒为一个时间单位,当然如果要求不是很准确的话,时间单位可以调大一点)

    问题 请问有没有别的更好方法或者想法可以实现这个调用频率的限制?

    Update:基于令牌桶的开放平台限流框架:limiter,持续开发中…

    回答

    nginx的limit_req_zone就符合你想要的这种需求,它是使用令牌桶算法的.具体你可以看一下.

    96dfb7e85860a8d6d5bab7e0dedea539.png

    为每个secret维护一个长度为100的队列

    当队列长度为100的时候,取出队列头

    判断时间是否超过1分钟,则accept

    如果不足1分钟则deny

    然后shift和push队列即可

    令牌桶

    ====

    令牌桶算法是网络流量整形(Traffic Shaping)和速率限制(Rate Limiting)中最常使用的一种算法。典型情况下,令牌桶算法用来控制发送到网络上的数据的数目,并允许突发数据的发送。

    Redid 的expire功能完全可以满足你的需求

    实现一个栈,存放请求信息,请求来源地或者来源用户,以及请求时间。

    然后处理请求就是,系统当前时间向前规定时间内的请求出栈,以供处理。

    由于后进先出的选择,出栈的请求应当是按时间顺序倒序排列。然后再统计这些数据中同源数据的个数,小于规定数目的向后转发进行处理,大于规定数目的返回超限的响应。

    上述的操作在拦截器或者过滤器中完成。题主觉得这样的思路可行么?

    我的想法是这样的:

    为每个SECRET维护一个固定60秒的数组, key为每秒的时间(key_1: 第一秒的UNIX时间戳, key_2: 第二秒的UNIX时间戳), value为每秒访问的次数, value的默认值为0.

    如果访问时间在这个数组中(通过key_1 + 60来进行判断), 则找到对应的key, 例如key_n.判断由key_1 + … + key_n的总和是否大于100, 如果小于100, 则key_n++

    如果访问时间不在这个数组中, 数组进行初始化, key_1为当前访问时间对应的第一秒的值, 例如当前访问时间为: 2015-06-29 17:09:30, 则key_1为2015-06-29 17:09:01对应的UNIX时间戳

    可否创建一个计数器,在cache中set一个key(根据用户标识)=0,设置timeout=60s,这样,新的请求到来,判断是否存在这个key,如果存在key,value>100,则拒绝请求,如果<100,则将其value+1,如果key不存在,则重新set一次,初始值为0,执行请求

    维护一个List,其中的每个Object包含的内容有

    {

    secret:’ad822513232′,

    ip:’127.0.0.1′,

    timestamp:’231321321′,

    count:1

    };

    当一个请求来的时候,根据secret(或ip,依据需求)查找是否存在该对象,不存在则创建,timestamp为当前时间,count为1。如果存在对象obj,则先判断当前请求时间和obj.timestamp的时间差是否大于60s,大于就判断obj过期,然后重置它,obj.timestamp= currentTime,obj.count=1,小于则判断count和100的大小关系,大于则obj.count++,大于或等于100则废弃当前请求。

    接口请求频率,你最后采取的什么方案?谢谢

    展开全文
  • 给调用者一个SECRET,每次调用者需要调用接口的时候,都需要把这个SECRET带过来(为了安全需要对key进行一系列加密的措施)一个SECRET就代表一个调用者,把相应的SECRET的调用次数放入缓存中(必须确保次数增加的原子)...

    如何限制接口调用者对接口的调用频率?

    问题:对某个对外暴露的接口加一个限制:调用者一分钟之内调用次数不能超过100次,如果超过100次就直接返回给调用者失败的信息。

    给调用者一个SECRET,每次调用者需要调用接口的时候,都需要把这个SECRET带过来(为了安全需要对key进行一系列加密的措施)

    一个SECRET就代表一个调用者,把相应的SECRET的调用次数放入缓存中(必须确保次数增加的原子性),并且把SECRET当做缓存的SECRET(这里如果区分方法的话,可以把方法和KEY做一次加密)。

    这里主要的难点就是,如何判断调用者1分钟之内调用次数是否超过100?也就是很难确实这个1分钟的开始时间。

    我现在的想法是:分别把当前秒调用的次数存入缓存。比如说,当前调用者调用次数为3,那么我就往缓存中加入KEY=SECRET_1,VALUE=3;然后调用者在第二秒调用的次数为4,那么就往缓存中加入KEY=SECRET_2,VALUE=3;如此循环,当循环到61秒的时候替换KEY=SECRET_1中得VAALUE,每次调用的时候计算SECRET_1~SECRET_60的值来判断调用次数,是否超过100次。(这里具体一秒钟调用几次,需要通过时间戳来算出是第几秒。这里以60秒为时间周期,并且以秒为一个时间单位,当然如果要求不是很准确的话,时间单位可以调大一点)

    问题 请问有没有别的更好方法或者想法可以实现这个调用频率的限制?

    Update:基于令牌桶的开放平台限流框架:limiter,持续开发中...

    展开全文
  • 当我们使用swagger,进行接口测试,怕接口安全,担心暴露。可采用两种方式1.环境权限配置对swagger文档配置只在测试环境可访问,生产环境不可访问。@profile({"dev","test"})如以上配置,则只有在dev以及test环境...

    当我们使用swagger,进行接口测试,怕接口不安全,担心暴露。可采用两种方式

    1.环境权限配置

    对swagger文档配置只在测试环境可访问,生产环境不可访问。

    3691c154654ac6826aeb2c86e738c98f.png

    @profile({"dev","test"})

    如以上配置,则只有在dev以及test环境有效,在生产环境不可访问。

    2.账户权限配置

    在1.9.0版本时,针对swagger的资源接口,swaggerbootstrapui提供了简单的basic认证功能。

    如果是springboot项目可在yml文件配置

    2.1:配置yml文件

    73c5e5aa4997478195f030ac87aaa34a.png

    swagger:

    production: false

    basic:

    enable: true

    username: admin

    password: 123456

    以上分别为启用,并且用户名为admin.密码为123456。

    切记swagger.production 不可设置为true,否则将屏蔽所有资源

    2.2:在swaggerconfig中添加注解

    @enableswaggerbootstrapui

    57cfc3cb417766d71cc4bd483f859882.png

    结果就是此时访问需要通过用户密码才可进行访问

    f1ae3a9a8fc7abc57fce40ff727fa3c9.png

    此时密码账号不对,不可登录。

    到此这篇关于swagger添加权限验证保证api(接口)安全性的文章就介绍到这了,更多相关swagger权限验证内容请搜索萬仟网以前的文章或继续浏览下面的相关文章希望大家以后多多支持萬仟网!

    如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

    展开全文
  • 前言前后端分离的开发方式,我们以接口为标准来进行推动,定义好接口,各自开发自己的功能,最后进行联调整合。无论是开发原生的APP还是webapp还是PC端的软件,只要...数据的安全性非常重要,特别是用户相关的信息,...

    d2554487b03766ae9a96f5ed58c5c38b.png

    前言

    前后端分离的开发方式,我们以接口为标准来进行推动,定义好接口,各自开发自己的功能,最后进行联调整合。无论是开发原生的APP还是webapp还是PC端的软件,只要是前后端分离的模式,就避免不了调用后端提供的接口来进行业务交互。

    网页或者app,只要抓下包就可以清楚的知道这个请求获取到的数据,这样的接口对爬虫工程师来说是一种福音,要抓你的数据简直轻而易举。

    数据的安全性非常重要,特别是用户相关的信息,稍有不慎就会被不法分子盗用,所以我们对这块要非常重视,容不得马虎。

    如何保证API调用时数据的安全性?通信使用https

    请求签名,防止参数被篡改

    身份确认机制,每次请求都要验证是否合法

    APP中使用ssl pinning防止抓包操作

    对所有请求和响应都进行加解密操作

    等等方案…….

    对所有请求和响应都进行加解密操作

    方案有很多种,当你做的越多,也就意味着安全性更高,今天我跟大家来介绍一下对所有请求和响应都进行加解密操作的方案,即使能抓包,即使能调用我的接口,但是我返回的数据是加密的,只要加密算法够安全,你得到了我的加密内容也对我没什么影响。

    像这种工作最好做成统一处理的,你不能让每个开发都去关注这件事情,如果让每个开发去关注这件事情就很麻烦了,返回数据时还得手动调用下加密的方法,接收数据后还得调用下解密的方法。

    为此,我基于Spring Boot封装了一个Starter, 内置了AES加密算法。GitHub地址如下:

    https://github.com/yinjihuan/spring-boot-starter-encrypt

    先来看看怎么使用,可以下载源码,然后引入即可,然后在启动类上增加@EnableEncrypt注解开启加解密操作:

    @EnableEncrypt

    @SpringBootApplication

    public class App {

    public static void main(String[] args) {

    SpringApplication.run(App.class, args);

    }

    }

    增加加密的key配置:

    spring.encrypt.key=abcdef0123456789

    spring.encrypt.debug=false

    spring.encrypt.key:加密key,必须是16位

    spring.encrypt.debug:是否开启调试模式,默认为false,如果为true则不启用加解密操作

    为了考虑通用性,不会对所有请求都执行加解密,基于注解来做控制

    响应数据需要加密的话,就在Controller的方法上加@Encrypt注解即可。

    @Encrypt

    @GetMapping("/list")

    public Response queryNews(String city) {

    return Response.ok(city);

    }

    当我们访问/list接口时,返回的数据就是加密之后base64编码的格式。

    还有一种操作就是前段提交的数据,分为2种情况,一种是get请求,这种暂时没处理,后面再考虑,目前只处理的post请求,基于json格式提交的方式,也就是说后台需要用@RequestBody接收数据才行, 需要解密的操作我们加上@Decrypt注解即可。

    @Decrypt

    @PostMapping("/save")

    public Response savePageLog(@RequestBody PageLogParam logParam, HttpServletRequest request) {

    pageLogService.save(logParam);

    return Response.ok();

    }

    加了@Decrypt注解后,前端提交的数据需要按照AES加密算法,进行加密,然后提交到后端,后端这边会自动解密,然后再映射到参数对象中。

    上面讲解的都是后端的代码,前端使用的话我们以js来讲解,当然你也能用别的语言来做,如果是原生的安卓app也是用java代码来处理。

    前端需要做的就2件事情:

    统一处理数据的响应,在渲染到页面之前进行解密操作

    当有POST请求的数据发出时,统一加密js加密文件请参考我GitHub中encrypt中的aes.js,crypto-js.js,pad-zeropadding.js

    我们以axios来作为请求数据的框架,用axios的拦截器来统一处理加密解密操作

    首先还是要封装一个js加解密的类,需要注意的是加密的key需要和后台的对上,不然无法相互解密,代码如下:

    var key = CryptoJS.enc.Latin1.parse('abcdef0123456789');

    var iv = CryptoJS.enc.Latin1.parse('abcdef0123456789');

    // 加密

    function EncryptData(data) {

    var srcs = CryptoJS.enc.Utf8.parse(data);

    var encrypted = CryptoJS.AES.encrypt(srcs, key, {

    mode : CryptoJS.mode.ECB,

    padding : CryptoJS.pad.Pkcs7

    });

    return encrypted.toString();

    }

    // 解密

    function DecryptData(data) {

    var stime = new Date().getTime();

    var decrypt = CryptoJS.AES.decrypt(data, key, {

    mode : CryptoJS.mode.ECB,

    padding : CryptoJS.pad.Pkcs7

    });

    var result = JSON.parse(

    CryptoJS.enc.Utf8.stringify(decrypt).toString()

    );

    var etime = new Date().getTime();

    console.log("DecryptData Time:" + (etime - stime));

    return result;

    }

    axios拦截器中统一处理代码:

    // 添加请求拦截器

    axios.interceptors.request.use(function (config) {

    // 对所有POST请加密,必须是json数据提交,不支持表单

    if (config.method == "post") {

    config.data = EncryptData(JSON.stringify(config.data));

    }

    return config;

    }, function (error) {

    return Promise.reject(error);

    });

    // 添加响应拦截器

    axios.interceptors.response.use(function (response) {

    // 后端返回字符串表示需要解密操作

    if(typeof(response.data) == "string"){

    response.data = DecryptData(response.data);

    }

    return response;

    }, function (error) {

    return Promise.reject(error);

    });

    到此为止,我们就为整个前后端交互的通信做了一个加密的操作,只要加密的key不泄露,别人得到你的数据也没用,问题是如何保证key不泄露呢?

    服务端的安全性较高,可以存储在数据库中或者配置文件中,毕竟在我们自己的服务器上,最危险的其实就时前端了,app还好,可以打包,但是要防止反编译等等问题。

    如果是webapp则可以依赖于js加密来实现,下面我给大家介绍一种动态获取加密key的方式,只不过实现起来比较复杂,我们不上代码,只讲思路:

    加密算法有对称加密和非对称加密,AES是对称加密,RSA是非对称加密。之所以用AES加密数据是因为效率高,RSA运行速度慢,可以用于签名操作。

    我们可以用这2种算法互补,来保证安全性,用RSA来加密传输AES的秘钥,用AES来加密数据,两者相互结合,优势互补。

    其实大家理解了HTTPS的原理的话对于下面的内容应该是一看就懂的,HTTPS比HTTP慢的原因都是因为需要让客户端与服务器端安全地协商出一个对称加密算法。剩下的就是通信时双方使用这个对称加密算法进行加密解密。

    客户端启动,发送请求到服务端,服务端用RSA算法生成一对公钥和私钥,我们简称为pubkey1,prikey1,将公钥pubkey1返回给客户端。

    客户端拿到服务端返回的公钥pubkey1后,自己用RSA算法生成一对公钥和私钥,我们简称为pubkey2,prikey2,并将公钥pubkey2通过公钥pubkey1加密,加密之后传输给服务端。

    此时服务端收到客户端传输的密文,用私钥prikey1进行解密,因为数据是用公钥pubkey1加密的,通过解密就可以得到客户端生成的公钥pubkey2。然后,自己在生成对称加密,也就是我们的AES,其实也就是相对于我们配置中的那个16的长度的加密key,生成了这个key之后我们就用公钥pubkey2进行加密,返回给客户端,因为只有客户端有pubkey2对应的私钥prikey2,只有客户端才能解密,客户端得到数据之后,用prikey2进行解密操作,得到AES的加密key,最后就用加密key进行数据传输的加密,至此整个流程结束。

    spring-boot-starter-encrypt原理

    最后我们来简单的介绍下spring-boot-starter-encrypt的原理吧,也让大家能够理解为什么Spring Boot这么方便,只需要简单的配置一下就可以实现很多功能。

    启动类上的@EnableEncrypt注解是用来开启功能的,通过@Import导入自动配置类

    @Target({ElementType.TYPE})

    @Retention(RetentionPolicy.RUNTIME)

    @Documented

    @Inherited

    @Import({EncryptAutoConfiguration.class})

    public @interface EnableEncrypt {

    }

    EncryptAutoConfiguration中配置请求和响应的处理类,用的是Spring中的RequestBodyAdvice和ResponseBodyAdvice,在Spring中对请求进行统计处理比较方便。如果还要更底层去封装那就要从servlet那块去处理了。

    @Configuration

    @Component

    @EnableAutoConfiguration

    @EnableConfigurationProperties(EncryptProperties.class)

    public class EncryptAutoConfiguration {

    /**

    * 配置请求解密

    * @return

    */

    @Bean

    public EncryptResponseBodyAdvice encryptResponseBodyAdvice() {

    return new EncryptResponseBodyAdvice();

    }

    /**

    * 配置请求加密

    * @return

    */

    @Bean

    public EncryptRequestBodyAdvice encryptRequestBodyAdvice() {

    return new EncryptRequestBodyAdvice();

    }

    }

    通过RequestBodyAdvice和ResponseBodyAdvice就可以对请求响应做处理了,大概的原理就是这么多了。

    本文仅代表作者个人观点,不代表SEO研究协会网官方发声,对观点有疑义请先联系作者本人进行修改,若内容非法请联系平台管理员。更多相关资讯,请到SEO研究协会网www.seoxiehui.cn学习互联网营销技术请到巨推学院www.jutuiedu.com。

    展开全文
  • 前言如何保证API调用时数据的安全性?对所有请求和响应都进行加解密操作spring-boot-starter-encrypt原理前言前后端分离的开发方式,我们以接口为标准来进行推动,定义好接口,各自开发自己的功能,最后进行联调整合...
  • 作者:尹吉欢来源:微信公众号-猿天地一、前言前后端分离开发方式,我们以接口为标准来进行推动,定义好接口,各自开发自己功能,最后进行联调整合。无论是开发原生APP还是webapp还是PC端软件,只要是前后端...
  • ​前后端分离开发方式,我们以接口为标准来进行推动,定义好接口,各自开发自己功能,最后进行联调整合。无论是开发原生APP还是webapp还是PC端软件,只要是前后端分离模式,就避免不了调用后端提供的接口来...
  • 接口的安全性主要围绕Token、Timestamp和Sign三个机制展开设计,保证接口的数据不会被篡改和重复调用,下面具体来看:Token授权机制用户使用用户名密码登录后服务器给客户端返回一个Token(通常是UUID),并将Token-...
  • Java 提供接口的安全问题

    千次阅读 2017-08-02 10:50:57
    问题: Java给别人提供接口,接口安全怎么保证? 1.请求合法校验,考虑用token方式保证接口不被其他人访问。 2.数据校验,白名单方式验证数据,确保不出现异常数据和注入攻击。 3.数据加密,对数据进行加密...
  • 提到线程安全,可能大家第一反应是要确保接口对共享变量操作要具体原子。实际上,在多线程编程中我们需要同时关注可见、顺序和原子问题。本篇文章将从这三个问题出发,结合实例详解volatile如何保证可见...
  • 既然 ArrayList 是线程不安全怎么保证线程安全性呢?或者有什么替代方案? 大部分人会脱口而出:用Vector,这样只会让面试官鄙视!除了Vector,你还会别吗? 至少还得说得上这种: java.util.Collections....
  • java.util.Collections.SynchronizedList它能把所有 List 接口的实现类转换成线程安全的List,比 Vector 有更好的扩展和兼容,很可惜,它所有方法都是带同步对象锁的,和 Vector 一样,它不是性能最优的 ...
  • 移动APP接口怎么保证安全性的,可以采用https,或者是非对称加密。 接口加密目的是防止被别人用抓包工具,抓包后篡改数据。 关于加密算法常见有对称加密(DES)和非对称加密(RSA) 对称加密(DES):加密...
  • 么面试官会问你,既然 ArrayList 是线程不安全怎么保证线程安全性呢?或者有什么替代方案?往下看,看我如何碾压他!大部分人会脱口而出:用Vector,这样只会让面试官鄙视!除了Vector,你还会别吗?你...
  • 一、Zookeeper实现分布式锁概述 1、项目中有使用到分布式锁吗? 案例:需要生成订单号方案 ...怎么保证接口幂等 --- 就是怎么保证接口不允许有重复 不要生产重复。如订单号 保证幂等。 案例生成订单ID...
  • 密码学意义上的安全随机数,要求必须保证其不可预测。2. 怎么得到安全的随机数可以直接使用真随机数产生器产生的随机数。或者使用真随机数产生器产生的随机数做种子,输入密码学安全的伪随机数产生器产生密码学...
  • 那么面试官会问你,既然 ArrayList 是线程不安全怎么保证线程安全性呢?或者有什么替代方案?往下看,看我如何碾压他!大部分人会脱口而出:用Vector,这样只会让面试官鄙视!除了Vector,你还会别吗?你...
  • 密码学意义上的安全随机数,要求必须保证其不可预测。2. 怎么得到安全的随机数可以直接使用真随机数产生器产生的随机数。或者使用真随机数产生器产生的随机数做种子,输入密码学安全的伪随机数产生器产生密码学...
  • 怎么保证的?4.volatile为什么不能保证原子5.volatile和synchronized比较6.线程状态和wait、join、sleep、yield区别7.线程和进程区别8.Thread类start方法和run方法区别?为什么不直接运行run方法?9....
  • 分布式服务接口的幂等如何设计(比如不能重复扣款)? 分布式服务接口请求的顺序如何保证? 如何自己设计一个类似 Dubbo 的 RPC 框架? CAP 定理的 P 是什么? 分布式锁 Zookeeper 都有哪些应用场景? 使用 ...
  • java 面试题 总结

    2009-09-16 08:45:34
    但通常情况下,由于Java Bean是被容器所创建(如Tomcat),所以Java Bean应具有一个无参构造器,另外,通常Java Bean还要实现Serializable接口用于实现Bean持久Java Bean实际上相当于微软COM模型中本地...
  • 开放接口的安全性 对外开放的接口,如何保证安全通信,防止数据被恶意篡改等攻击呢?怎么证明是你发的请 求呢? 比较流行的方式一搬是 加密 加签 注:加密是密文传输,接收方需要解密。加签是...
  • java——内部类

    2019-08-26 21:05:15
    继承:不可以被外部类单独...2、内部类不可以被单独继承,可以很好地保证安全性(?这里话该怎么说?) 3、a类不能即继承b又继承c,但是可以先继承b,然后排除自己内部类实现c功能的接口(一般包都是对外暴...
  • 47.在 java 程序中怎么保证多线程运行安全? 48.多线程锁升级原理是什么? 49.什么是死锁? 50.怎么防止死锁? 51.ThreadLocal 是什么?有哪些使用场景? 52.说一下 synchronized 底层实现原理? 53....
  • 么面试官会问你,既然 ArrayList 是线程不安全怎么保证线程安全性呢?或者有什么替代方案?往下看,看我如何碾压他!大部分人会脱口而出:用Vector,这样只会让面试官鄙视!除了Vector,你还会别吗?你...
  • 很多京东pop商家以及第三方软件服务商在对接京东开放...答: 如果您的应用和京东的JOS对接后,需要获取一些与用户紧密相关的信息(如订单丶商品丶促销等),为保证数据的安全性和隐私性,需要取得用户的同意,引导用户...
  • 12.1. 多线程原子操作的安全性 31 13. Cas怎么实现unsafe? 32 13.1. Unsafe 32 13.2. CAS 32 13.3. 由CAS分析AtomicInteger原理 33 13.4. CAS的缺点 35 14. Map数据结构? 35 14.1. 一、定义 36 14.2. 二、构造函数...
  • 4.1.7 有没有有顺序的Map实现类,如果有,他们是怎么保证有序的。 4.1.8 抽象类和接口的区别,类可以继承多个类么,接口可以继承多个接口么,类可以实现多个接口么。 4.1.9 继承和聚合的区别在哪。 4.2.0 IO模型有...

空空如也

空空如也

1 2 3
收藏数 49
精华内容 19
关键字:

java怎么保证接口的安全性

java 订阅