【问题标题】:Stored Android Accounts for Authentication of Rails + Devise Accounts用于 Rails + 设计帐户身份验证的存储 Android 帐户
【发布时间】:2012-08-24 09:07:18
【问题描述】:

总结:我正在尝试使用 Android 应用程序上存储的 Google 帐户来验证本机应用程序中的用户,并使用 Rails 3 + Devise 应用程序提供的 API,但我被卡住了。

详情: 我们有一个应用程序 (http://push-poll.com),它可以让用户从他们的一群朋友那里收集反馈。我们还构建了一个原生 Android 应用程序。我们的网络应用程序允许您使用您的 Google 帐户登录,我们希望将该功能扩展到本机 Android 应用程序。 Web 应用通过 Devise(用于帐户权限)+ Omniauth(用于 Google 帐户信息和 OAuth 交互)来完成此操作。

版本: Android 2.1+、Rails 3.2.2、Devise 2.1.2、Omniauth 1.1.0

建议的身份验证工作流程:

  1. 用户在 Android 应用程序上点击“使用 Google 帐户登录”
  2. 用户使用 AccountManager 选择 Android 设备上存储的帐户并授予权限
  3. Android 应用向 Rails API 发送 Google 帐户令牌
  4. Rails 应用程序将帐户令牌发送到 Google OAuth API
  5. Google 返回成功和帐户信息(特别是姓名 + 电子邮件)
  6. Rails 应用通过电子邮件地址查找/创建用户
  7. Rails 应用程序从用户帐户创建/读取/更新访问令牌
  8. Rails 访问令牌已重新调整到 Android 应用程序(这是我们的应用程序当前使用标准登录处理 api 访问的方式)
  9. Android 应用在所有 API 调用中都包含 Rails 访问令牌

我浏览了 Google 的文档,但我完全停留在 (4) 和 (5) 上。一旦我有了 Google 提供的电子邮件地址,一切都会像现在一样正常工作(对于标准登录或 Google/Omniauth/Devise 帐户)。根据我的最佳猜测,这可以通过以下任一方式解决:

  • 为与网络应用共享的 Android 应用创建 API/密钥,以便向 Google Accounts API 发出请求
  • 找到一个 Google API 端点,我可以简单地对 Android 帐户令牌进行身份验证并返回帐户详细信息

至少一个星期以来,我一直在用头撞墙。

仅供参考:我是网络开发人员,我们的 Android 开发人员非常友好地为我提供了一个已删除的 Android 应用,该应用会将访问令牌从 Android 发送到我选择的 API 端点。

【问题讨论】:

    标签: android ruby-on-rails oauth devise oauth-2.0


    【解决方案1】:

    好的,所以我能够通过更好地了解 OAuth 来解决这个问题。显然,令牌能够在不同的服务器之间传递,谁持有它们并不重要,它们继续发挥作用。

    因此,使用 Android 的 AccountManager,我能够为范围 userinfo.email 提取具有足够权限的令牌,然后将其发送到服务器。然后服务器就可以命中了:

    https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=TOKENVALUE

    注意:这是通过 HTTPS 发送到 Rails 应用程序的 - 你不应该通过互联网以明文形式发送令牌。

    这是我们如何做到这一点的部分剪辑:

    # Use Google's Token Verification scheme to extract the user's email address
    token = params[:token]
    uri = URI.parse("https://www.googleapis.com")
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_NONE
    path = "/oauth2/v1/tokeninfo?access_token=#{token}"
    resp, data = http.get(path)
    data = JSON.parse(data)
    if resp.code == "200"
      # Find a user
      @user = User.where(:email => data["email"]).first
      if !@user
        #Create a user with the data we just got back
      end
    else
      # Bad or revoked token 
    end
    

    【讨论】:

    • 使用 Google 的 oAuth 操场,我发现这行得通,但路径不同:googleapis.com/oauth2/v2/userinfo?access_token=ya.......(/userinfo 而不是 /tokeninfo)
    • 另外,这是 /v2 而不是 /v1。顺便说一句,我没有使用 New::HTTP,而是使用了 HTTPClient,因为它更简单,原因在 olabini.com/blog/2008/08/ruby-https-web-calls
    • 还有一件事——我认为最后的 if/then 是错误的。你可能想要一个嵌套的“if/then”,如果找不到@user,就会发生“创建用户”。
    • mahemoff 是对的——我很快就搞定了。如果 !@user 应该发生用户创建。更新
    猜你喜欢
    • 2018-10-11
    • 2012-06-21
    • 2021-12-04
    • 1970-01-01
    • 2018-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-27
    相关资源
    最近更新 更多