如何使用node.js实现安全的REST API [英] How to implement a secure REST API with node.js

查看:110
本文介绍了如何使用node.js实现安全的REST API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始使用node.js,express和mongodb来规划一个REST API。该API为网站(公共和私人区域)提供数据,也可能是移动应用程序。前端将使用AngularJS开发。



有些日子我读了很多关于保护REST API的内容,但是我没有得到最终的解决方案。据我所知,使用HTTPS提供基本的安全性。但是,如何在这种用例中保护API:




  • 只有网站/应用的访问者/用户才能获得网站/应用程序公共区域的数据


  • 只有经过身份验证和授权的用户才能获取私人区域的数据(仅限用户授予的数据)权限)




目前我只想允许有活动会话的用户使用API​​。为了授权用户,我将使用护照和许可,我需要为自己实施一些东西。全部位于HTTPS顶部。



有人可以提供一些最佳做法或体验吗?我的架构是否缺乏?

解决方案

我也遇到过同样的问题。我正在建设的网站可以从手机和浏览器访问,所以我需要一个api,允许用户注册,登录和做一些特定的任务。此外,我需要支持可扩展性,在不同的进程/机器上运行相同的代码。



由于用户可以CREATE资源(也称为POST / PUT操作),您需要确保API。您可以使用oauth,或者您可以构建自己的解决方案,但请记住,如果密码真的很容易发现,所有解决方案都可能会损坏。基本思想是使用用户名,密码和令牌来认证用户,也称为apitoken。可以使用 node-uuid 生成此apitoken,密码可以使用 pbkdf2



然后,您需要保存会话某处。如果将其保存在一个普通对象的内存中,如果您杀死服务器并重新启动它,会话将被销毁。此外,这是不可扩展的。如果您使用haproxy在机器之间进行负载平衡,或者仅使用工作人员,则此会话状态将存储在单个进程中,因此如果同一用户重定向到另一进程/机器,则需要再次进行身份验证。因此,您需要将会话存储在一个共同的地方。这通常使用redis进行。



当用户进行身份验证(username + password + apitoken)时,会为会话生成另一个令牌,也称为accesstoken。再次,使用node-uuid。发送给用户accesstoken和userid。 userid(key)和accesstoken(value)被存储在redis中并且过期的时间,例如1h。



现在,每次用户使用其余的api进行任何操作时,都需要发送用户名和accesstoken。



如果您允许用户使用其余的api进行注册,则需要创建一个具有管理员权限的管理员帐户,并将其存储在移动应用中(加密用户名+密码+ apitoken),因为新用户赢得



网络也使用这个api,但你不需要使用apitokens。您可以使用express与redis商店或使用与上述相同的技术,但绕过apitoken支票,并返回给用户的用户id + accesstoken在一个cookie。



如果你有私人区域将用户名与允许的用户进行身份验证时进行比较。



总结:





没有apitoken的替代方法是使用HTTPS并发送用户名和密码在授权标题中并以redis缓存用户名。


I start planning a REST API with node.js ,express and mongodb. The API provides data for a website (public and private area) and maybe later a mobile app. The frontend will be developed with AngularJS.

For some days I read a lot about securing REST APIs, but I don’t get to a final solution. As far as I understand is to use HTTPS to provide a basic security. But how I can protect the API in that use cases:

  • Only visitors/users of the website/app are allowed to get data for the public area of the website/app

  • Only authenticated and authorized users are allowed to get data for private area (and only data, where the user granted permissions)

At the moment I think about to only allow users with a active session to use the API. To authorize the users I will use passport and for permission I need to implement something for myself. All on the top of HTTPS.

Can somebody provide some best practice or experiences? Is there a lack in my "architecture"?

解决方案

I've had the same problem you describe. The web site I'm building can be accessed from a mobile phone and from the browser so I need an api to allow users to signup, login and do some specific tasks. Furthermore, I need to support scalability, the same code running on different processes/machines.

Because users can CREATE resources (aka POST/PUT actions) you need to secure your api. You can use oauth or you can build your own solution but keep in mind that all the solutions can be broken if the password it's really easy to discover. The basic idea is to authenticate users using the username, password and a token, aka the apitoken. This apitoken can be generated using node-uuid and the password can be hashed using 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.

When the user is authenticated (username+password+apitoken) generate another token for the session, aka accesstoken. Again, with node-uuid. Send to the user the accesstoken and the userid. The userid (key) and the accesstoken (value) are stored in redis with and expire time, e.g. 1h.

Now, every time the user does any operation using the rest api it will need to send the userid and the accesstoken.

If you allow the users to signup using the rest api, you'll need to create an admin account with an admin apitoken and store them in the mobile app (encrypt username+password+apitoken) because new users won't have an apitoken when they sign up.

The web also uses this api but you don't need to use apitokens. You can use express with a redis store or use the same technique described above but bypassing the apitoken check and returning to the user the userid+accesstoken in a cookie.

If you have private areas compare the username with the allowed users when they authenticate. You can also apply roles to the users.

Summary:

An alternative without apitoken would be to use HTTPS and to send the username and password in the Authorization header and cache the username in redis.

这篇关于如何使用node.js实现安全的REST API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆