保护我的Node.js应用程序的REST API?


68

我可以在REST API上提供一些帮助。我正在编写一个使用Express,MongoDB并在客户端具有Backbone.js的Node.js应用程序。我花了最后两天的时间来尝试解决所有这些问题,但运气并不好。我已经签出了:

我想使后端和前端尽可能分开,所以我认为使用精心设计的REST API会很好。我的想法是,如果我打算开发一个iPhone应用程序(或类似的东西),它可以使用API​​来访问数据。

但是,我希望这是安全的。用户已登录我的Web应用程序,并且我想确保我的API安全。我阅读了有关OAuth,OAuth 2.0,OpenID,Hmac,哈希等的信息。

...但是我还是很困惑。也许是在深夜,或者我的大脑被炸了,但是我真的可以在这里做些什么。创建安全API的步骤是什么?

任何帮助,任何信息,任何示例,步骤或任何东西都将是不错的。请帮忙!


你最终做了什么?
Morteza Shahriari Nia 2014年

Answers:


28

这是一种不同的思考方式:

让我们暂时假设您没有使用API​​。您的用户登录到该应用程序并提供了一些凭据,然后您向该用户提供了cookie或类似的令牌,用于标识该用户已登录。然后,该用户请求包含受限信息的页面(或创建/修改/删除它),因此您检查此令牌以确保允许用户查看该信息。

现在,在我看来,您唯一要更改的就是信息的传递方式。而不是将信息作为呈现的HTML传递,而是将信息作为JSON返回并在客户端呈现。您对服务器的AJAX请求将携带与以前相同的登录令牌,因此我建议仅检查该令牌,并以相同的方式将信息限制为“恰好允许用户知道”。

您的API现在和登录时一样安全-如果有人知道访问api所需的令牌,那么他们也将登录到该站点,并且无论如何都可以访问所有信息。最好的一点是,如果您已经实现了登录,那么您实际上并不需要做更多的工作。

诸如OAuth之类的系统的重点是通常通过第三方应用程序并以开发人员的身份提供这种“登录”方法。对于iPhone应用程序或类似应用程序来说,这可能是一个很好的解决方案,但这已成为未来。接受不止一种身份验证方法的API没错!


那么我是否认为自己想得太多?我已经在进行“普通”身份验证...用户登录,将为会话创建cookie,站点将检查用户是否已登录各个“安全”部分。所以本质上就是这样!...我只是想得太多了,试图解决OAuth等问题,但实际上,它仍然只是基本的auth内容...现在,如果是这样,那就太好了!我想,如果有的话,我确实需要在服务器上对SSL进行排序,但是除此之外,我可以只使用普通的身份验证过程吗?
littlejim84 '02

1
可能是我在这里遗漏了一些东西,但是这不是违反API的基本规则吗?即:没有服务器端状态?如果服务器需要跟踪令牌,则意味着保持状态,这应该是一个不可以不的地方:-)
Dieter 2012年

2
@Dieter它是无状态的,因为该状态未在http中传递
Typo Johnson

2
@dieter可以构造令牌,以便服务器不必维护已发行令牌的数据库即可验证令牌。使用私钥对令牌签名,以便具有匹配的公钥的任何人都可以验证a)令牌是由受信任的服务器发出的(真实性),b)令牌尚未修改(保真度)。令牌是状态数据,因此服务器可以是无状态的。OAuth2不会定义令牌的内容,而只是定义如何获取令牌的内容。JSON Web令牌(JWT)定义了可与OAuth2一起使用的安全令牌格式。
dthorpe

1
@dthorpe谢谢!这就说得通了。TypoJohnson,根据记录,我很确定这不是API中无状态的含义。无状态= API可以处理任何请求而无需记住任何内容。因此,服务器2是否处理一分钟前由服务器1服务的客户端都没有关系。因此,在某些情况下,(通过客户端)将状态传递到http中实际上是可以的。如果不可能,那么他们只需要在所有API服务器之间共享数据库或缓存即可
Dieter

39

为了提高安全性/复杂性,请按以下顺序进行:

基本HTTP身份验证

许多API库都可以让您构建它(例如Django中的Piston),也可以让您的网络服务器来处理它。Nginx和Apache都可以使用服务器指令通过简单的b64编码密码来保护站点。这不是世界上最安全的东西,但至少是用户名和密码!

如果您使用的是Nginx,则可以在主机配置中添加一个部分,如下所示:

auth_basic "Restricted";
auth_basic_user_file /path/to/htpasswd;

(放在您的location /方块中)

文件:http//wiki.nginx.org/HttpAuthBasicModule

您需要获取python脚本来生成该密码,然后将输出结果放入文件中:http : //trac.edgewall.org/browser/trunk/contrib/htpasswd.py?format=txt

只要Nginx可以访问文件,文件的位置就无关紧要。

HTTPS

确保服务器到应用程序之间的连接安全,这是最基本的方法,可以防止中间人攻击。

您可以使用Nginx进行此操作,它的文档非常全面:http : //wiki.nginx.org/HttpSslModule

为此自己签名的证书就可以了(而且是免费的!)。

API密钥

这些文件可以是您喜欢的任何格式,但是它们给您带来了撤销访问权限的好处。如果您正在开发连接的两端,可能不是您的理想解决方案。当您有第三方使用API​​(例如Github)时,通常会使用它们。

OAuth

OAuth 2.0就是其中之一。虽然我不知道该规范的基础工作原理,但是它是大多数身份验证(Twitter,Facebook,Google等)的事实上的标准,并且有大量的库和文档可帮助您实现这些规范。话虽如此,它通常用于通过请求第三方服务进行身份验证来对用户进行身份验证。

既然您完成了开发的两端,那么将您的API放在Basic HTTP Auth后面并通过HTTPS提供服务就足够了,尤其是如果您不想浪费时间搞乱OAuth。


好答案。我看到OAuth似乎是标准。但是似乎有两足式OAuth 1.0,三足式OAuth 1,然后是此OAuth 2 ...所以我应该研究OAuth 2?...我当时在考虑HTTPS / SSL,但是我不确定像iPhone应用程序这样的传输方式(甚至可能)吗?...关于OAuth的另一个问题,我既可以是提供者又可以是消费者,还是需要(如您所说)需要使用第三方进行身份验证?在这种情况下,使用第三方不是太可取,因为它不是真正的那种应用程序。感谢您的详细答复!
littlejim84 '02

OAuth 2是更新的OAuth。我相信1.0现在被认为是“不好的”。iPhone肯定可以通过HTTPS(移动Safari中的Github!)运行。
ghickman '02

可以同时使用,但通常OAuth用于通过第三方进行身份验证。正如@mjtamlyn在下面指出的那样,使用您当前的身份验证系统肯定是可能的。我已经用部分步骤中的一些步骤更新了我的答案。
ghickman '02

谢谢您的回答!那给了我很多信息,因为所有这些auth东西对我来说都是很新的:)
littlejim84'2

1
我刚刚看过这篇文章,简要介绍了OAuth1和OAuth2 stormpath.com/blog/secure-your-rest-api-right-way
Fabian Leutgeb 2014年


0

对保护任何Web应用程序有效的提示

如果您想保护您的应用程序安全,那么绝对应该从使用HTTPS而不是HTTP开始,这可以确保在您和用户之间创建安全的通道,从而防止嗅探来回发送给用户的数据并有助于保留数据。交换了机密。

您可以使用JWT(JSON Web令牌)来保护RESTful API,与服务器端会话相比,它具有许多好处,主要包括:

1-更具可扩展性,因为您的API服务器将不必为每个用户维护会话(当您有很多会话时,这可能是一个沉重的负担)

2-JWT是自包含的,并且具有定义用户角色的声明,例如,他可以在日期和到期日访问和发布的内容(此日期之后,JWT将无效)

3-更易于处理负载平衡器,并且如果您有多个API服务器,因为您不必共享会话数据,也无需配置服务器将会话路由到同一服务器,那么只要JWT的请求碰到任何服务器,就可以对其进行身份验证和授权

4-减轻数据库负担,不必为每个请求不断存储和检索会话ID和数据

5-如果您使用强键对JWT进行签名,则JWT不会被篡改,因此您可以信任随请求一起发送的JWT中的声明,而不必检查用户会话以及他是否被授权,您只需检查JWT,然后就可以知道该用户可以执行的操作。

Node.js特定的库来实现JWT:

许多库提供了创建和验证JWT的简便方法,例如:在node.js中,最受欢迎的一种是jsonwebtoken,也可以使用同一库或使用express-jwtkoa-jwt来验证JWT (如果您使用的是使用快递/ koa)

由于REST API通常旨在使服务器保持无状态,因此JWT与该概念更加兼容,因为每个请求都是使用自包含(JWT)的授权令牌发送的,而与服务器会话相比,服务器无需跟踪用户会话服务器是有状态的,以便记住用户及其角色,但是,会话也被广泛使用并具有其优点,您可以根据需要进行搜索。

需要注意的重要一件事是,您必须使用HTTPS将JWT安全地交付给客户端,并将其保存在安全的地方(例如,本地存储中)。

您可以从此链接了解有关JWT的更多信息。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.