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

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

问题描述

我开始计划使用 node.js、express 和 mongodb 的 REST API.API 为网站(公共和私人区域)提供数据,之后可能还会为移动应用程序提供数据.前端将使用 AngularJS 开发.

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.

有几天我读了很多关于保护 REST API 的内容,但我没有找到最终的解决方案.据我了解是使用HTTPS来提供基本的安全性.但是我如何在这些用例中保护 API:

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)

目前我正在考虑只允许具有活动会话的用户使用 API.为了授权用户,我将使用护照,为了获得许可,我需要为自己实现一些东西.一切都在 HTTPS 之上.

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"?

推荐答案

我遇到了与您描述的相同的问题.我正在构建的网站可以通过手机和浏览器访问,所以我需要一个 api 来允许用户注册、登录和执行一些特定任务.此外,我需要支持可扩展性,在不同的进程/机器上运行相同的代码.

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.

因为用户可以创建您需要保护 API 的资源(也称为 POST/PUT 操作).您可以使用 oauth,也可以构建自己的解决方案,但请记住,如果密码真的很容易被发现,则所有解决方案都可能被破解.基本思想是使用用户名、密码和令牌(即 apitoken)对用户进行身份验证.这个 apitoken 可以使用 node-uuid 生成,密码可以使用 pbkdf2

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

然后,您需要将会话保存在某处.如果你将它保存在一个普通对象的内存中,如果你杀死服务器并再次重新启动它,会话将被破坏.此外,这是不可扩展的.如果您使用 haproxy 在机器之间进行负载平衡,或者您只是使用 worker,则此会话状态将存储在单个进程中,因此如果同一用户被重定向到另一个进程/机器,则需要再次进行身份验证.因此,您需要将会话存储在一个公共位置.这通常使用 redis 完成.

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)时,为会话生成另一个令牌,也就是访问令牌.同样,使用 node-uuid.将访问令牌和用户 ID 发送给用户.用户 ID(密钥)和访问令牌(值)存储在 redis 中,并带有过期时间,例如1 小时.

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.

现在,每次用户使用 rest api 执行任何操作时,都需要发送用户 ID 和访问令牌.

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

如果您允许用户使用rest api注册,您需要使用admin apitoken创建一个admin帐户并将它们存储在移动应用程序中(加密用户名+密码+apitoken),因为新用户将没有他们注册时的 apitoken.

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.

网络也使用这个api,但你不需要使用apitoken.您可以将 express 与 redis 存储一起使用,或者使用上述相同的技术,但绕过 apitoken 检查并将用户 ID+访问令牌在 cookie 中返回给用户.

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.

总结:

没有 apitoken 的替代方法是使用 HTTPS 并在 Authorization 标头中发送用户名和密码并将用户名缓存在 redis 中.

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天全站免登陆