1

概要:Androidアプリケーションに保存されているGoogleアカウントを使用して、Rails 3 + Deviseアプリケーションによって提供されるAPIを使用して、ネイティブアプリケーションのユーザーを認証しようとしていますが、行き詰まります。

詳細:ユーザーがたくさんの友達からフィードバックを集めることができるアプリケーション(http://push-poll.com)があります。また、ネイティブのAndroidアプリケーションも構築しました。Googleのウェブアプリでは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アプリはGoogleアカウントトークンをRailsAPIに送信します
  4. RailsアプリはアカウントトークンをGoogleOAuthAPIに送信します<-これは私が立ち往生しているところです
  5. Googleは成功とアカウント情報(具体的には、名前とメールアドレス)を返します
  6. Railsアプリはメールアドレスでユーザーを検索/作成します
  7. Railsアプリはユーザーアカウントからアクセストークンを作成/読み取り/更新します
  8. RailsアクセストークンはAndroidアプリに再調整されます(これは、現在、アプリが標準ログインでAPIアクセスを処理する方法です)
  9. Androidアプリでは、すべてのAPI呼び出しにRailsアクセストークンが含まれています

私はグーグルのドキュメンテーションを精査しました、しかし私は完全に(4)と(5)に固執しています。Googleが提供するメールアドレスを取得すると、すべてが現在と同じように機能します(標準ログインまたはGoogle / Omniauth / Deviseアカウントのいずれか)。私の推測では、これは次のいずれかで解決できます。

  • GoogleアカウントAPIをリクエストするために、ウェブアプリと共有されるAndroidアプリのAPI/秘密鍵を作成します
  • Google APIエンドポイントを見つけるAndroidアカウントトークンを認証して、アカウントの詳細を返すだけです

私は少なくとも一週間、これの壁に頭をぶつけてきました。

参考:私はウェブ開発者です。Android開発者は親切にも、Androidから選択したAPIエンドポイントにアクセストークンを送信するスタブアウトされたAndroidアプリを提供してくれました。

4

1 に答える 1

2

OK、それで私は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
于 2012-08-31T17:00:28.377 に答える