我开始用node.js,express和mongodb规划一个REST API。API为网站(公共区域和私人区域)提供数据,以后可能还会为移动应用程序提供数据。前端将使用AngularJS开发。
最近几天,我读了很多关于保护REST api的文章,但我没有找到一个最终的解决方案。就我所理解的是使用HTTPS来提供基本的安全性。但是我如何在用例中保护API:
只有网站/应用程序的访问者/用户被允许获取网站/应用程序公共区域的数据
仅允许经过身份验证和授权的用户获取私有区域的数据(并且仅允许用户授予权限的数据)
目前,我只考虑允许具有活动会话的用户使用API。为了授权用户,我将使用护照和许可,我需要为自己实现一些东西。都在HTTPS之上。
有人能提供一些最佳实践或经验吗?我的“架构”是否存在缺陷?
如果你想要保护你的应用程序,那么你肯定应该开始使用HTTPS而不是HTTP,这确保了你和用户之间建立一个安全通道,防止嗅探发送给用户的数据,并有助于保持数据交换的机密性。
你可以使用jwt (JSON Web令牌)来保护RESTful api,与服务器端会话相比,这有很多好处,主要是:
1-更具可伸缩性,因为你的API服务器不必为每个用户维护会话(当你有很多会话时,这可能是一个很大的负担)
2- JWT是独立的,有定义用户角色的声明,例如,他可以访问什么,在日期和到期日发布(在此之后JWT将无效)
3-跨负载平衡器更容易处理,如果你有多个API服务器,因为你不需要共享会话数据,也不需要配置服务器将会话路由到同一台服务器,无论何时使用JWT的请求击中任何服务器,都可以进行身份验证和授权
4-对数据库的压力更小,你不必为每个请求不断存储和检索会话id和数据
5-如果你使用强密钥签署JWT, JWT是不能被篡改的,所以你可以信任随请求发送的JWT中的声明,而不必检查用户会话以及他是否被授权,你可以只检查JWT,然后你就知道这个用户可以做什么了。
许多库提供了在大多数编程语言中创建和验证jwt的简单方法,例如:在node.js中最流行的一个是jsonwebtoken
由于REST api通常旨在保持服务器无状态,所以JWT更符合这一概念,因为每个请求都带有自包含的授权令牌(JWT),而服务器无需跟踪用户会话,而会话使服务器有状态,以便记住用户及其角色,然而,会话也被广泛使用,并有其优点,如果你想要,你可以搜索。
需要注意的一件重要事情是,您必须使用HTTPS安全地将JWT交付给客户端,并将其保存在安全的地方(例如在本地存储中)。
您可以从这个链接了解更多关于jwt的信息
我也遇到过你描述的同样的问题。我正在建设的网站可以从手机和浏览器访问,所以我需要一个api,让用户注册,登录和做一些特定的任务。此外,我需要支持可伸缩性,相同的代码在不同的进程/机器上运行。
因为用户可以创建资源(也就是POST/PUT动作),所以你需要保护你的api。您可以使用oauth,也可以构建自己的解决方案,但请记住,如果密码很容易被发现,那么所有的解决方案都可能被破坏。其基本思想是使用用户名、密码和令牌(即apitoken)对用户进行身份验证。这个apitoken可以使用node-uuid生成,密码可以使用pbkdf2进行散列
Then, you need to save the session somewhere. If you save it in memory in a plain object, if you kill the server and reboot it again the session will be destroyed. Also, this is not scalable. If you use haproxy to load balance between machines or if you simply use workers, this session state will be stored in a single process so if the same user is redirected to another process/machine it will need to authenticate again. Therefore you need to store the session in a common place. This is typically done using redis.
当用户通过身份验证(用户名+密码+apitoken)时,为会话生成另一个令牌,即accesstoken。同样,使用node-uuid。向用户发送accesstoken和userid。userid (key)和accesstoken (value)存储在带有和过期时间的redis中,例如1h。
现在,每当用户使用其余api执行任何操作时,它都需要发送userid和accesstoken。
如果你允许用户使用其余api注册,你需要创建一个admin apitoken帐户,并将其存储在移动应用程序中(加密用户名+密码+apitoken),因为新用户注册时不会有apitoken。
web也使用这个api,但你不需要使用apitokens。您可以在redis存储中使用express,也可以使用上述相同的技术,但可以绕过apitoken检查,并在cookie中向用户返回userid+accesstoken。
如果您有私有区域,则在验证时将用户名与允许的用户进行比较。您还可以为用户应用角色。
简介:
另一种没有apitoken的方法是使用HTTPS,在授权头中发送用户名和密码,并在redis中缓存用户名。