首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >保护REST API,而无需重新发明轮子

保护REST API,而无需重新发明轮子
EN

Stack Overflow用户
提问于 2011-08-30 10:28:46
回答 3查看 52.5K关注 0票数 74

在设计REST API时,通常会先对用户进行身份验证吗?

我正在寻找的典型用例是:

  • 用户想要获取数据。当然,酷,我们喜欢分享!获取公共API密钥并读取!
  • 用户要存储/更新数据...哇,等等!你是谁,你能做到吗?

我想构建它一次,并允许例如一个网络应用程序,一个安卓应用程序或一个iPhone应用程序使用它。

REST API似乎是符合以下要求的合乎逻辑的选择

为了说明我的问题,我将使用一个简单的例子。

我在数据库中有一个项目,它有一个rating属性(整数1到5)。

如果我正确理解REST,我会使用我选择的语言实现GET请求,返回csv、xml或json,如下所示:

代码语言:javascript
复制
http://example.com/product/getrating/{id}/

假设我们选择JSON并返回:

代码语言:javascript
复制
{
  "id": "1",
  "name": "widget1",
  "attributes": { "rating": {"type":"int", "value":4} }
}

这对于面向公众的API来说是很好的。我明白这一点。

我有很多问题是如何将其与安全模型结合起来?我习惯了web应用的安全性,我有一个会话状态来识别我的用户,这样我就可以控制他们可以做什么,无论他们决定发送给我什么。据我所知,这不是RESTful,所以在这种情况下这将是一个糟糕的解决方案。

我将尝试使用另一个使用相同项目/评分的示例。

如果用户"JOE“想要将评级添加到项目

这可以使用以下命令来完成:

代码语言:javascript
复制
http://example.com/product/addrating/{id}/{givenRating}/

此时,我想存储"JOE“给产品{id}的评级为{givenRating}的数据。

问:我如何知道请求来自"JOE“而不是"BOB”。

此外,如果是为了更敏感的数据,比如用户的电话号码呢?

到目前为止,我得到的是:

1)使用HTTP的内置功能对每个请求进行身份验证,无论是普通HTTP还是HTTPS。

这意味着现在每个请求都采用以下形式:

代码语言:javascript
复制
https://joe:joepassword@example.com/product/addrating/{id}/{givenRating}/

2)使用像亚马逊的具有私钥和公钥的S3一样的方法:http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/

3)无论如何都要使用cookie,并打破REST的无状态部分。

第二种方法对我来说似乎更好,但我想知道我真的必须重新发明整个东西吗?散列、存储、生成密钥等等都是我一个人做的吗?

这听起来很像在典型的web应用程序中使用会话,然后自己重写整个堆栈,对我来说,这通常意味着“你做错了”,特别是在处理安全问题时。

编辑:我想我也应该提到OAuth。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-08-30 10:49:22

5年后编辑

使用OAuth2!

以前版本的

不,绝对不需要使用cookie。它的安全性不及HTTP Digest、OAuth或亚马逊的亚马逊网络服务(这并不难复制)的一半。

您应该这样看待cookie :它和Basic/Digest/OAuth/一样是一个身份验证令牌,但不太合适。

但是,只要会话cookie的内容不影响从服务器返回的资源的内容,我认为使用cookie本身并不违反RESTful原则。

Cookie是邪恶的,停止使用它们。

票数 21
EN

Stack Overflow用户

发布于 2011-08-30 10:47:03

不要担心成为"RESTful",担心的是安全性。我是这样做的:

步骤1:用户使用凭据访问身份验证服务。

第2步:如果凭证检出,返回指纹、会话id等,并将它们放入共享内存以便稍后快速检索,或者使用数据库,如果您不介意增加几毫秒的web服务周转时间的话。

步骤3:在每个web服务脚本的顶部添加一个入口点调用,以验证每个web服务请求的指纹和会话id。

步骤4:如果指纹和会话id无效或超时,则重定向到身份验证。

请阅读以下内容:

RESTful Authentication

票数 21
EN

Stack Overflow用户

发布于 2013-12-03 22:06:57

3年后编辑

我完全同意Evert的观点,将OAuth2与HTTPS一起使用,不要重复发明轮子!:-)

通过更简单的REST APIs不是针对第三方客户端- JSON Web Tokens也可以很好。

以前版本的

无论如何都要使用cookie,并打破REST的无状态部分。

不要使用会话,使用会话你的REST服务不会有很好的可扩展性...这里有两种状态:应用程序状态(或客户端状态或会话)和资源状态。应用程序状态包含会话数据,并由REST客户端维护。资源状态包含资源属性和关系,并由REST服务维护。您可以非常容易地确定某个特定变量是应用程序状态的一部分还是资源状态的一部分。如果数据量随着活动会话数量的增加而增加,则它属于应用程序状态。例如,当前会话的用户标识属于应用程序状态,但是用户或用户权限列表属于资源状态。

因此,REST客户端应该存储标识因素,并将其与每个请求一起发送。不要将REST客户端与HTTP客户端混淆。它们是不一样的。如果REST客户端使用curl,那么它也可以在服务器端,或者它可以创建例如服务器端的http only cookie,它可以通过CORS与REST服务共享。唯一重要的是,REST服务必须对每个请求进行身份验证,因此您必须随每个请求一起发送凭据(用户名、密码)。

  • 如果你写了一个客户端REST客户端,那么这可以通过SSL + HTTP auth来完成。在这种情况下,您可以在服务器上创建credentials -> (identity, permissions)缓存,以加快身份验证速度。请注意,如果您清除该缓存,并且用户发送相同的请求,他们将得到相同的响应,只是需要更长的时间。您可以将此与会话进行比较:如果您清除了会话存储,那么用户将获得一个status: 401 unauthorized response...
  • If您编写了一个服务器端REST客户端,并且您通过curl将标识因子发送到REST服务,那么您有两个选择。您也可以使用http auth,或者您可以在REST客户端中使用会话管理器,而不是在REST服务中。
  • 如果有人不受信任地编写您的REST客户端,那么您必须编写一个应用程序来对用户进行身份验证,并为他们提供可用性,以决定他们是否想要将权限授予不同的客户端。Oauth是一个已经存在的解决方案。Oauth1更安全,oauth2不太安全,但更简单,我猜这个问题还有其他几种解决方案……你不需要重新发明这个。使用oauth有完整的身份验证和授权解决方案,例如:wso identity server.

Cookie不一定是不好的。您可以以RESTful的方式使用它们,直到它们保持客户端状态,而服务仅保持资源状态。例如,您可以将购物车或首选分页设置存储在cookies中...

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7238094

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档