【问题标题】:how can I authenticate a user from a web app to an API?如何将用户从 Web 应用程序验证到 API?
【发布时间】:2015-01-10 04:38:25
【问题描述】:

这似乎是一个被广泛询问的问题,在阅读了大量有关该主题的文档之后,我仍然不确定是否正确理解了所有内容(我认为愚蠢是一个可能的答案;))。

我正在尝试构建一个向用户提供服务的 API。用户将通过 Facebook 或任何 OpenId 提供商进行连接(我将 Facebook 分开,因为他们实现了自己的连接系统)。

(我认为这是一个好方法,因为我不会存储用户的密码,并且最终在遇到类似 Gawker 问题的情况下问题会更少。)

当客户端(网络应用程序、移动应用程序等)向 API 发出请求时,必须随请求发送一个指示符,以识别哪个用户正在使用该应用程序。这通常通过在身份验证期间定义的 令牌 使用。

但是关于身份验证,我找不到任何有价值的示例、教程、关于如何正确实现它的说明。

我会(尝试)解释:

在我的(快乐护理熊的精彩世界)中,我将我的项目分为多个部分:

  • RESTful API
  • 将使用 api 的 Web 应用程序。理想情况下,我正在考虑制作一个完整的 html/css/js 项目,而不需要任何服务器端工作(php/python/java 或其他)
  • 移动应用程序
  • windows/mac/linux 应用程序

据我所见,每次有人问如何实现 RESTful API 身份验证时,都会弹出三个主要答案:

  • HTTP 基本(+最好是 SSL)/摘要方式
  • OAuth
  • OpenId

由于我不会存储用户的密码,所以第一个对我来说很重要,但是另外两个让我感到困惑。

但是 OAuth 和 OpenId 相同,一个 (OpenId) 代表 Authentication(问题的基础),而第二个 (OAuth) 代表授权

当 Twitter 为其 API 实现 OAuth 时,他们并没有实现身份验证系统,而是设置了一种方法来指示他们的用户应用程序 X 想要访问用户帐户(在不同的访问级别)。如果用户当前没有登录 Twitter,他将首先必须验证自己,然后授权当前应用程序访问他的数据。

所以,澄清一下,OAuth 不是身份验证机制,它是:

允许安全 API 的开放协议 授权 (来源:http://oauth.net/

那么,验证用户身份的唯一方法就是使用 OpenId。然后,该死的就成真了。

如果我以一个完全由 html/css/js 组成的 Web 应用程序为例,没有服务器端组件,则与 API 进行通信。

网络应用必须向 API 表明当前使用 API 的用户是 X 先生。

为此,Web 应用程序会显示一个包含 OpenId 提供者列表的弹出窗口,要求用户进行身份验证。用户单击其中一个,被重定向(或打开一个新的弹出窗口)到 OpenId 提供程序,指示他的登录名/密码,通过 OpenId 提供程序进行身份验证,返回成功并带有令牌(我简化了通信)。

太好了,网络应用现在知道用户确实是 X 先生。但是 API 仍然有任何线索!

最后,我的问题很简单:如何通过网络应用程序通过 OpenId 向 API 验证 x 先生,然后,网络应用程序和 api 如何保留当前正在使用的 X 先生的信息Web 应用程序,当然还有 API。

非常感谢您的帮助!

-编辑格式

【问题讨论】:

    标签: api authentication rest openid


    【解决方案1】:

    您并不想使用 OpenID 登录 API。正如您所说,OpenID 用于 Authentication,即谁,而 OAuth 用于 Authorization,即我是否被允许?但您的结构表明您将使用 API 作为后端,使用 Web 应用作为前端。

    最好的方法是在 web-app 上使用 OpenID 对用户进行身份验证,然后 web-app 连接到 API 并存储 OpenID 凭据。然后,网络应用程序知道用户是谁,并可以提供服务。 API 与用户没有任何关系,只是它存储了自己的数据。

    OpenID 和 OAuth 的根本区别在于其用途。在您的情况下,您可能会遇到这样的情况:

    --------          ---------            -------
    | User | <------> |  App  | <--------> | API |
    --------  OpenID  ---------   (OAuth)  -------
    

    用户从不直接与 API 交互:谁愿意手动发送 HTTP 请求? (lol) 相反,该服务是通过应用程序提供的,可以选择使用 OAuth 进行授权。但是,在单个应用程序访问 API 的情况下,您可以将应用程序 API 连接设为内部并且永远不会暴露它。

    【讨论】:

    • 我几乎同意您的建议,但有一个限制:webapp 如何将 openid 凭据发送到 api ? api 必须确保这些凭据对特定用户有效,它不能只信任 webapp,因为其他应用程序也可以连接到 api 并可能窃取用户的身份。可能的想法是将 openid 服务器的响应发送到 API,包括 assoc_handle 密钥,然后,API 服务器将(再次)请求 openid 提供程序检查“is_valid:true”并匹配数据库中的用户.我说的对吗?
    • 否(完全不)。您必须区分充当外部世界和数据(基础)之间统一层的 API。你可以按照你的建议去做,但这本质上意味着在 API 中集成一个应用程序(不过,这对你来说可能没问题)。至于信任,您可以轻松地使用公钥加密和签名来确保只有您的(或已批准的)应用程序才能访问/更改敏感数据。此外,OpenID 凭据只是 URL——您与用户关联。我想用户必须登录才能设置这个关联,所以:没问题。
    • 嗯,显然,要信任一个应用程序,您需要 a) 自己编写,或者 b) 信任开发人员,阅读代码。无论如何,这无关紧要。您只需要在应用程序和 api 之间实现公钥(或其他)加密和签名,确保 a) 数据来自受信任的应用程序,并且 b) 数据不会被篡改。根据定义,您不能相信不受信任的应用程序会做正确的事情。您可以检查 api 中的 openid,但如果您让任何应用程序访问数据,它仍然很容易受到攻击...您必须确保您正在与值得信赖的人交谈应用程序。
    • 答案:权限。见上文:make sure that only your (or approved) app accesses/changes the sensitive data。扩展我之前的评论:You've got to make sure you're talking to a trustworthy app... 对于那些 sensitive 字段。任何人都会理智地打开“开放”访问他们的密码列表,甚至是散列吗?接受您自己的陈述:“问题 解决方案并非所有 API 都是开放的,任何人都可以使用我的 API 的非敏感部分。”
    • 好吧,打开另一个问题,并投票/标记为正确我的答案/cmets...声誉增益将帮助我“资助”我的努力。关闭cmets:1)没有完美的答案; 2) WebID 看起来很有趣; 3) ...帮到你真是太好了!
    【解决方案2】:

    (如果你不想看,下面的列表总结了整个想法)

    一个可能的解决方案 (如果我错了告诉我) 是在消费者(网络应用程序、移动应用程序等)中显示登录表单,用户点击它的提供程序(myopenid ,谷歌等)打开一个弹出窗口进行登录。 棘手的部分是 return_to 参数将设置为 API,而不是网站

    API 将重新发送 check_authentication 并获取 is_valid:true(或不)。 在此步骤中,应用程序将向返回身份验证状态(处理、失败、成功)的特定 url 查询 api。在处理过程中,会向用户显示一个指示符(加载 gif),如果成功/失败,则会向用户显示结果。

    如果 api 接收到 is_valid:true,那么它将向 openid 服务器询问有关用户的信息,例如电子邮件、名字、姓氏,并将它们与用户的数据库进行比较。如果匹配,api会在自己和应用程序之间创建一个会话,如果用户是新用户,它会创建一个新条目,然后是会话。

    会话将是具有特定持续时间的唯一令牌(可能等于 openid 服务器 assoc_handle 持续时间?)

    这似乎是可能的,但我不是安全专家。

    为了解释更简单,这里有一个小“地图”:

    注意:Provider 是 OpenId 服务器(提供认证信息)

    • 用户进入 web 应用并点击其提供商的登录图标(Google for ex)
    • webapp 打开一个包含提供者登录页面和访问页面的弹出窗口,并指定一个 return_to 到 Api
    • 提供者向 API 发送信息
    • Api 通过 check_authentication 验证这些信息
    • 如果无效,API 会向 webapp(每 x 秒询问一次 api)指示失败
    • 如果有效,Api 会向提供商询问有关用户的信息,例如电子邮件、显示名称等
    • 如果用户存在,则创建会话
    • 如果用户是新用户,则会将他添加到数据库并创建会话
    • Api 返回身份验证的状态(在本例中为成功),并带有一个令牌会话,Web 应用程序将使用该令牌会话进行进一步的请求。

    【讨论】:

    • 我不同意。编辑问题是为了提供更多信息或更好地排序问题。在这里,我展示了我的问题的可能解决方案。也许不是最好的,但它仍然是一个答案。
    • 好的。但是你为什么要问What do you think ??这将答案作为一个问题......但没关系。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-16
    • 2013-12-04
    • 1970-01-01
    • 1970-01-01
    • 2019-09-05
    • 1970-01-01
    • 2014-06-13
    相关资源
    最近更新 更多