最近想拿一个小项目来试水RESTful Web API,项目只有几个调用,比较简单,但同样需要身份验证,如果是传统的网站的话,那不用说,肯定是用户名+密码在登录页获得登录Token,并把登录Token记在Cookie和Session中作为身份标识的这种方式,但现在不同了,关键是RESTful,这意味着我们设计出来的这些API是无状态的(Stateless),下一次的调用请求和这一次的调用请求应该是完全无关的,也就是说,正宗的RESTful Web API应该是每次调用都应该包含了完整的信息,没错,包括身份信息!

那如何确保安全?传输时给密码做MD5加密?得了吧!这样做只能让你自己感觉“安全”点,其实没什么任何用处,利用现在的技术(有种叫什么Rainbow Table啥的来着?本人外行,不是很懂)很快就能算出明文密码了,而且如何防止挟持和重发攻击?

也许你想到了,SSL,如果你打算采用SSL,请忘记一切自行设计的加密方案,因为SSL已经帮你做好了一切,包括防止监听,防止挟持,防止重发……一切都帮你考虑好了,你大胆地把明文密码写在你的包中就OK了,我向你保证没问题。

但SSL的缺点是服务器端配置相对有点复杂,更关键的就是客户端对此支持可能不好,那你考虑一种自己的加密方法,有木有?我这里提供一种方法,思路来自于:http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/,我只是把上面的内容中整理了一下变成了我的方法。(传说中的剽窃?呵呵)方法描述如下:

  1. 假设有一个用户,用户名是guogangj,密码是123456(呃……这也能叫密码?)
  2. 他要GET http://test.com/api/orders/
  3. 于是把 http://test.com/api/orders/这个URL和一个新生成的GUID拼在一起,再用123456这个密码执行对称加密,生成的密文为XXXXOOOOXXXXOOOO(假设而已)
  4. 数据包中带上用户名guogangj和XXXXOOOOXXXXOOOO这个密文,发送给服务器
  5. 服务器收到包后,根据guogangj这个用户名到数据库中查找到123456这个密码
  6. 服务器使用123456这个密码来解密XXXXOOOOXXXXOOOO这个密文,得到了明文,即http://test.com/api/orders/这个URL和前面由客户端生成的那个GUID
  7. 服务器到一个全局的集合中查找这个GUID,看看是否已经存在,如果存在,则验证不通过,如果不存在,就将其放入这个集合中。这是为了避免重发攻击。这个全局的集合会越来越大,所以还要定期清理。
  8. 服务器再比对解密出来的URL和用户真实请求的URL是否一致,如果一致,那么认为这是合法用户,验证通过!

这是大致过程,如果数据库里找不到该用户,或者解密错误,都被认为验证不通过。以下是一些改进:

  1. 数据库中的密码最好做一下摘要(MD5之类的),客户端对应地也要做一下。
  2. 在生成密文的时候可以考虑加入另外一些不希望被明文传输的敏感内容,甚至可以加入IP地址,并在服务器端验证。
  3. 并非每次都要真正去数据库里拿一次用户信息,也许你有更好的办法,比如一个简单的缓存(不过需要处理缓存更新的问题),或者当你的系统大到一定程度的时候,你考虑使用统一的服务来获取用户信息,这就不是缓存那么简单了,里面的文章很多,我相信现在大规模的门户网站都有自己的一套复杂的机制,所以表明上看RESTful Web API很“低效”,但这种RESTFul的思路和模式却在实际中有很大的可塑性和威力。

这种方法应该足够安全了!

密码根本没有在网络上传输,密文采用的是非验证的对称加密,没有密钥就无法逆转,URL验证避免了传统的身份挟持攻击(即拦截一个用户的包并冒充此用户来访问其它的资源,即便无法破解用户密码), 再用GUID来避免了重发攻击,唯一需要担心的是用户泄露了自己的密码。

元芳,你怎么看?

如何实现RESTful Web API的身份验证相关推荐

  1. Asp.Net MVC及Web API添加身份验证及错误处理的过滤器

    先说身份验证的问题.无论是mvc还是api都有一个安全性的问题,未通过身份验证的人能不能访问的问题.我们新一个空项目时,默认是没有身份验证的,除非你在控制器类或者方法上面加上Authorize属性才会 ...

  2. ASP.NET Core 3.1 系列之 Web API 添加身份验证Jwt

    ASP.NET Core 3.1 系列之 Web API 中间件篇 (一) 身份验证(Jwt)中间件使用步骤 添加 NuGet程序包 添加包:Microsoft.AspNetCore.Authenti ...

  3. 对RESTful Web API的理解与设计思路

    距离上一篇关于Web API的文章(如何实现RESTful Web API的身份验证)有好些时间了,在那篇文章中提到的方法是非常简单而有效的,我在实际的项目中就这么用了,代码经过一段时间的磨合,已经很 ...

  4. 关于WEB ServiceWCFWebApi实现身份验证之WebApi篇

    之前先后总结并发表了关于WEB Service.WCF身份验证相关文章,如下: 关于WEB Service&WCF&WebApi实现身份验证之WEB Service篇. 关于WEB S ...

  5. 我所理解的RESTful Web API [设计篇]

    <我所理解的RESTful Web API [Web标准篇]>Web服务已经成为了异质系统之间的互联与集成的主要手段,在过去一段不短的时间里,Web服务几乎清一水地采用SOAP来构建.构建 ...

  6. django restful 请求_利用 Django REST framework 构建 RESTful Web API

    利用 Django REST framework 构建 RESTful Web API 终于到了动手操作的环节啦,这一节,我们以师生管理系统为例,带领大家搭建一套 framework Web API. ...

  7. 【视频教程】使用 ASP.NET Core 3.x 构建 RESTful Web API 已完结

    使用 ASP.NET Core 3.x 构建 RESTful Web API 的视频教程已经完结,共50讲,约10.5小时. B站可看,点击原文链接. 度娘盘可下载完整视频: https://pan. ...

  8. 学习笔记-Spring Boot 开发 RESTful Web API(一)

    题记: 本篇是Spring Boot 开发学习系列中基础知识学习的一部分,为 RESTful Web API 相关基础知识,为实践操作奠定理论基础. REST不是一个标准,而是一种软件应用架构风格.基 ...

  9. web api json_使用JSON Web令牌对Node ES6 API进行身份验证

    web api json In this guide, we'll be implementing token based authentication in our own node.js A.P. ...

最新文章

  1. SNV分析软件/工具
  2. 调整CentOS的文字登陆界面的分辨率
  3. python可以写桌面软件吗-python能写桌面程序吗
  4. Java编程的逻辑 (62) - 神奇的序列化
  5. python 使用sort()函数和正则表达式(lambda)对os.listdir()获取的文件夹文件列表进行重新排序 乱序排序
  6. php中svn上传项目直接访问不了,phpstorm8 通过svn导入项目后项目右键列表里没有subversion选项,无法提交和更新啊?...
  7. Unet美发实例分割,染发展示
  8. 零基础如何入门数据分析师?
  9. MATLAB修改代码字体
  10. 虚拟机安装linux输入密钥,远程连接虚拟机并做密钥认证
  11. 飞行控制PID算法——无人机飞控
  12. 联通发布沃Phone,全球为之震动
  13. c 字符输入与验证,毁人不倦
  14. 计算机专业的技能测试,中职学校计算机专业技能测试方法存在的主要问题及其对策...
  15. Android接入支付宝授权_小白教程
  16. phpstorm快速编辑模板技巧
  17. 脏读(dirty read)不可重复读(unrepeatable read)幻读(phantom problem)解析
  18. Android VideoView 视频播放器 仿抖音
  19. 捷联惯导系统学习2.2(等效旋转矢量)
  20. Navicat Premium 12.0.18 / 12.0.24安装与激活

热门文章

  1. java日记(2)------定时任务quartz浅析
  2. 郁闷的Alexa破10万。
  3. putty秘钥验证登录和xshell秘钥验证登录
  4. mysql中的多行查询结果合并成一个
  5. 从ramdisk根文件系统启动Linux
  6. linux中的while命令
  7. ARM裸机篇---启动代码分析
  8. python实现客户端和服务器端传输图片
  9. Android--SoundPool
  10. 【DeepLearning】Exercise:Sparse Autoencoder