最好的方法是限定几个可以访问 api 的域名,其他域名全部拒绝。
但是Access-Control-Allow-Origin
只能设置一个值,所以要多端共用,只有header("Access-Control-Allow-Origin:*");
Ajax跨域请求带上COOKIE
前端:'xhrFields': {'withCredentials': true}
(jquery ajax 设置),注意:Access-Control-Allow-Origin:*
与这个有冲突A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true
后端:header("Access-Control-Allow-Credentials: true");
跨域请求允许带cookie
web 客户端储存数据
前提:读写的数据必须要同域
使用 cookie 存储和读取
Web Storage (IE 789 无法使用)
IndexedDB 优点:支持事务,支持索引,可以存入对象,效率也不错。上手难
FileAPI 这个 API 可以结合 File 表单和 Formdata 从而实现异步上传文件。
如何保证只有自己的客户端才可以调用接口
api ajax 调用思考
如何保证多个客户端调用 api 接口时都是合法的(不是我们自己的客户端不能调用 api 接口拿数据),人为的(不是机器),数据安全的(不会被别人窃取数据),
首先要明白几点:
get 数据不可信,post 数据不可信,referer 数据不可信,host 域名 DNS 不可信,明文传输容易被抓包截取,cookie 可能被盗用!
Ajax 网站如何识别伪造请求?
好像参数不管怎么传,firebug 都可以看得到。
不过你可以在客户端将参数加密发送过去,如果在服务器端解密。
加密的密钥和解密的密钥才是最安全的
来路地址应该就是 referer,但这个东西一样是可以伪造的
好点的做法就是在验证用户时采用图片验证码的形式,给伪造带来很大的障碍(登录不了,就不能发帖),当然,你的图片验证码被分析出来了,那也是可能被攻破的.
另外 7L 的做法虽然可行,但是客户端加密的算法客户端也是能看到的,如果采用相同的加密方法一样可以伪造请求
首先只要是客户端发过来的,就不能叫伪造,
这个层面上要追究的其实是客户端的信用而非客户端的真伪.
你所谓的伪造应该指的是,用户在用你不希望的客户端(例如 机器人代替浏览器)
只能自己使用策略,不能相信客户端. 因为 referer 什么的都不可信.
如果是网站,限制客户端类型的原因通常为防止机器人或者为了展示广告.
常见策略:
服务端生成唯一 key 防止地址多次使用(甚至加上时间,过期无效)
有效图形验证码防止机器人
服务端生成唯一 key 禁止多端登陆(同一用户不同客户端同会话时间段多次登陆,key 不同则后登陆 key 有效,先登陆 key 强制注销).
服务端脚本+图形验证码 联合认证.例如如果一个下载页面同时 js 展示广告.
为了展示广告同时要防止盗链,那么在 js 展示广告逻辑同时还用 js 调处图形验证码.看一些当前流行的文件分享类站点,看他们的策略.例如 xxx 网盘.
http 是不安全,无状态协议。意味着你无法判断客服端是否是之前和你交流的某某。一般来说用 cookie 来识别客户端,但是 cookie 也可能被盗用。所以最应该做的是服务器段的逻辑,比如正常人可能一秒发一个帖子吗?不行就设定个帖子发送的间隔时间,只要应用层面可接受,那么不管其是人还是机器发过来的请求,都无所谓。
最常用的方法就是图形验证码。
至于判断数据来源,这个可以说完全没用了。现在很容易做到在合法来源处发送“不合法”数据。
自己目前的想法是,在服务器具端维护一个 api 调用 token 池,每次页面渲染,在服务器获取一个 api_access_token 储存在浏览器 cookie 中,每次 ajax 调用要将 api_access_token 作为参数发过来,服务器端验证过后,再处理 ajax 请求返回数据,
这个 api_access_token 生成规则,服务器端如何生成啊?何时失效啊?等等
总之,就是如何辨别是真用户,还是有人在模拟真实用户访问 api!!!
好的 api 应该满足
对于用户
易学习:有完善的文档及提供尽可能多的示例和可 copy-paste 的代码,像其他设计工作一样,你应该应用最小惊讶原则。
易使用:没有复杂的程序、复杂的细节,易于学习;灵活的 API 允许按字段排序、可自定义分页、 排序和筛选等。一个完整的 API 意味着被期望的功能都包含在内。
难误用:对详细的错误提示,有些经验的用户可以直接使用 API 而不需要阅读文档。
对于开发人员
易阅读:代码的编写只需要一次一次,但是当调试或者修改的时候都需要对代码进行阅读。
易开发:个最小化的接口是使用尽可能少的类以及尽可能少的类成员。这样使得理解、记忆、调试以及改变 API 更容易。
开发一个好的 api 的总结
面向用例设计
如果一个 API 被广泛使用了,那么就不可能了解所有使用该 API 的用户。如果设计者希望能够设计出被广泛使用的 API,那么必须站在用户的角度来理解如何设计 API 库,以及如何才能设计出这样的 API 库。设计思路
1面向用例的设计,收集用户建议,把自己模拟成用户,保证 API 设计的易用和合理
2保证后续的需求可以通过扩展的形式完成
3第一版做尽量少的内容,由于新需求可以通过扩展的形式完成,因此尽量少做事情是抑制 API 设计错误的一个有效方案
避免极端的意见 1.必须漂亮(API 不一定需要漂亮)
2.API 必须被正确地使用(用户很难理解如何正确的使用 API,API 的设计者要充分考虑 API 被误用的情况:如果一个 API 可能会被误用,那么它一定会被误用) 3.必须简单(我们总会面临复杂的需求,能两者兼顾的 API 是更好的 API) 4.必须高性能(性能可以通过其他手段优化,不应该影响 API 的设计) 5.必须绝对兼容(尽管本文一直提到如何保证兼容,但是我们仍然要意识到,一些极少情况下会遇到的不兼容是可以容忍的)有效的 API 评审 1.用例驱动,评审前必须提供完善的使用用例,确保用例的合理性和完备性。 2.一致性,是否与系统中其他模块的接口风格一致,是否与对称接口的设计一致。 3.简单明了,API 应该简单好理解,容易学习和使用的 API 才不容易被误用,给我们带来更多的麻烦。
4.API 尽可能少,如果一个 API 可以暴露也可以不暴露,那么就不要暴露他,等到用户真正有需求的时候再将它成为一个公开接口也不迟。 5.支持持续改进,API 是否能够方便地通过扩展的方式增加功能和优化。提高 API 的可测试性
API 需要是可测试的,测试不应依赖实现,测试充分的 API,尤其是经过了严格的“兼容性整合测试”的 API,更能保证在升级的过程中不出现兼容性问题。兼容性整合测试,是指一组测试用例集合,这组测试用例会站在使用者的立场上使用 API。在 API 升级以后,再检测这组测试用例是否能完全符合预期的通过测试,尽可能的发现兼容性问题。保证 api 的向后兼容
对于每一个 API 的设计者来说,都渴望做到“向后兼容”,因为不管是现在的 API 用户,还是潜在的 API 用户,都只信任那些可兼容的 API。但向后兼容有多个层次上的意义,而且不同层次的向后兼容,也意味着不同的重要性和复杂度。保持逐步改善
过去我们总希望能将现有的“不合理”的设计完全推翻,然后按照现在“美好”的思路,重新设计这个 API,但是在一段时间以后,又会碰到一样的状况,需要再推翻一次。如果我们没有有效的逐步改善的办法,依靠推翻现有设计,重新设计 API 只能让我们回到起点,然后重现之前的过程。 要有一套行之有效的持续改善的办法来在 API 兼容的同时,改善 API 使之更好。把握 api 的生命周期 1.告诉用户我们是如何设计的,避免误用,提供指导,错误的使用往往是缩短 API 寿命的一大杀手 2.提供试用期,API 不可能一开始就是稳定,经过试用的 API 才能有更强的生命力 3.为 API 分级:内部使用;二次开发使用;开发或试用中;稳定;弃用 API。避免 API 被滥用的同时,我们可以通过调整 API 的级别,来扩大其影响力,也能更优雅的结束一个 API 的生命周期。 4.开发 API 的过程其实就是一个沟通交流的过程。沟通的双方就是 API 用户和 API 设计者。
一些具体的实施方案
在一个 API 不可避免要消亡或者改变的时候,我们应该接受并且面对这个事实,下面列举了几种保证兼容性的前提下,对 API 进行调整的办法: 1.将 API 标记为弃用,重新建立一个新的 API。如果一个 API 不可避免要被消亡,这是唯一的办法。 2.为其添加额外的参数或者参数选项来实现功能添加 3.将现有 API 拆成两部分,提供一个精简的核心 API,过去的 API 通过封装核心 API 上实现。这通常用于解决用户需要一个代码精简的版本时。 4.在现有的 API 基础上进行封装,提供一个功能更丰富的包或者类。