ruby-on-rails-3 - OmniAuth 提供什么机制来确保安全登录?

标签 ruby-on-rails-3 authentication omniauth

使用omniauth 登录策略,未登录的用户被重定向到身份提供者。身份提供者将确保用户已登录,然后将用户重定向到回调 url,允许用户使用身份提供者的身份验证登录到第三方站点。Facebook 在此处的图表中解释了此工作流程:

https://developers.facebook.com/docs/user_registration/flows/

如何确保恶意用户不会欺骗此回调,以便他可以访问身份验证用户的第三方帐户?

最佳答案

与 Facebook 一样,Google 实现了 OAuth2.0 协议(protocol)来确认身份。我将带您了解 OAuth2.0 流程的安全性、OmniAuth 如何管理它,并向您展示如何深入了解它的实际运行情况。

由 OmniAuth 管理的 OAuth2.0 流程

The identity provider, will ensure a user is logged and then redirect the user to a callback url allowing the user to login to the third party site, using the identity provider's authentication.



让我扩展一下:身份提供者将用户重定向到您在向特定身份提供者(即 Facebook、Google 等)注册应用程序时提供的应用程序回调 URL。由于用户已被重定向,他们会向您的应用程序发送一个包含授权码的请求(由您的身份提供者在成功登录时提供)。

How is it assured that a malicious user does not spoof this callback so that he can gain access to the authenticating user's third party account?



这就是魔法发生的地方。我们的应用程序从用户那里获取此授权码,将其与我们在注册应用程序时收到的密码相结合,并与身份提供者交换这些密码以获得全能的访问码。具体来说,以下是确保此回调未被欺骗所采取的步骤:
  • 整个过程通过SSL(即HTTPS)进行管理。这使得拦截这些代码中的任何一个都非常困难。
  • 您的身份提供者通过在成功登录时提供授权代码并在从您的应用程序接收到该代码时验证此代码来验证用户的身份。
  • 您的身份提供者通过验证您的应用程序的密码来确保您的应用程序的身份。

  • 因此,拦截/解密代码将非常困难,并且如果您尝试使用伪造的授权代码来欺骗重定向,当您的服务器尝试使用您的身份验证提供者验证此代码时,您的登录请求将被拒绝。

    看到它在行动

    OmniAuth 在幕后管理这个过程的大部分。但是,以下代码应该可以让您看到它的实际效果:
    # Add the following gem to your Gemfile
    gem 'httplog', group: :development
    

    我们将使用 httplog gem。这实际上会将请求日志转储到我们的 log/development.log 文件中。我们需要初始化:
    # Create a new file: config/initializers/httplog.rb
    HttpLog.options[:logger] = Rails.logger if Rails.env.development?
    

    现在在终端中为您的应用程序启动一个新的 Rails 服务器:
    bundle install
    rails s
    

    在新选项卡中,跟踪您的开发日志:
    tail -f log/development.log
    

    继续并打开浏览器并使用您选择的身份提供者登录您的应用程序。打开跟踪您的开发日志的终端窗口,在用户( Started GET "/auth/google_oauth2/callback?state=1 )的回调请求之后,您应该看到如下内容:
    [httplog] Connecting: accounts.google.com:443
    [httplog] Sending: POST http://accounts.google.com:443/o/oauth2/token
    [httplog] Data: client_id=123412341234-1234h1234h1234h1234h.apps.googleusercontent.com&client_secret=12341234123412341234&code=123412341234123412341234&grant_type=authorization_code&redirect_uri=https%3A%2F%2Fyourapp.domain.com%2Fauth%2Fgoogle_oauth2%2Fcallback
    ....
    [httplog] Response:
    {
      "access_token" : "123412341234123412341234",
      "token_type" : "Bearer",
      "expires_in" : 3599,
      ...
    }
    

    这是您的服务器验证授权代码并验证访问 token 。接下来,OmniAuth 使用这个 token 来获取一些用户信息。再往下,您还应该看到:
    [httplog] Connecting: www.googleapis.com:443
    [httplog] Sending: GET http://www.googleapis.com:443/plus/v1/people/me/openIdConnect
    [httplog] Status: 200
    [httplog] Response:
    {
      "kind": "plus#personOpenIdConnect",
      "gender": "male",
      "sub": "1234123412341234",
      "name": "Matt",
      "given_name": "Matt",
      ...  
    }
    

    这表示 OmniAuth 使用访问 token 获取您请求的信息。

    很长的解释,但我希望它有所帮助。在推送到生产环境之前,请务必禁用或删除 httplog gem!

    关于ruby-on-rails-3 - OmniAuth 提供什么机制来确保安全登录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11489397/

    相关文章:

    ruby-on-rails - has_many :通过关联,shell 中的 Rails 控制台中的 "No Method Error",NoMethodError:#<ActiveRecord::Relation:> 的未定义方法

    ruby - 未定义方法 add_to_base

    ruby - 如何提取不在数据库中的标签?

    authentication - jmeter + influxdb后端: howto specify user name and password?

    mysql - 仅使用 AWS Cognito + mysql

    ruby-on-rails - 尝试注册用户时未初始化的常量 OmniauthCallbacksController

    ruby-on-rails - OmniAuth::NoSessionError - 您必须提供 session 才能使用 OmniAuth。 (在设计中配置)

    ruby-on-rails - Ruby on Rails 似乎是由 link_to 创建的自动转义 html

    ruby-on-rails - Omniauth facebook session Controller 在 Michael Hartl 教程之后创建 Action 集成

    linux - 登录到 linux 主机时运行多个命令