web-dev-qa-db-ja.com

Volleyによるトークン認証

ユーザー名/パスワードで認証し、後続のリクエストのために認証トークンを取得するサーバーがある場合、この問題に対処するための最良のアプローチは何でしょうか?

フローは次のようになります。-リクエストの開始-認証トークンがない場合-ユーザー名とパスワードで取得します-認証トークンでリクエストを行います-トークンの有効期限が切れたためにリクエストが失敗した場合は、ユーザー名とパスワードで新しい認証トークンを取得します-新しい認証トークンを使用してリクエストを再試行します-終了

ボレーにはすでにこの問題を解決する可能性のあるものがあるかもしれないことに気づきました-オーセンティケーター https://Android.googlesource.com/platform/frameworks/support/+/4474bc11f64b2b274ca6db5a1e23e8c1d143d5fa/volley/src/com/Android/volley /toolbox/Authenticator.Java getAuthToken()メソッドとinvalidateAuthToken()メソッドが含まれています。これらはまさに私が望むものです。しかし、それは図書館ではまったく使われていないようです。

17
MantasV

Longlive(LLT)トークンとshortlive(SLT)トークンを使用する認証システムにボレーを使用しました。

私は手動でそれをしました、しかしあなたがそれをすべてレイアウトしたらそれは本当に多くの仕事ではありませんでした。

すべてのセキュアリクエストに、onResponse()およびonErrorResponse()内のすべてのセキュアリクエストに共通のこのトークンメカニズムを処理できるbaseSecureRequestをサブクラス化させます。

これは小さなnode.jsスタイルになり、リクエストは他のリクエストを送信してコールバックを待ちます。


アプリには12の画面があり、認証アクセスが必要なのは半分だけです。したがって、各画面は、そのリクエストの要件について無知である必要があります。

シナリオA

  • 安全なリクエストを送信しようとします。メモリにSLTがないことに気付いたので、TokenRequestを作成します。
  • TokenRequestのonResponse()は、そのトークンをメモリに保存します(シングルトンセッションマネージャーがトークンまたは同様の遍在するクラスを保持できるようにします)
  • 次に、元の具象クラスのリクエストオブジェクトにコールバックして、新しく更新されたトークンを続行します。

シナリオB

  • 安全なリクエストを送信しましたが、SLTが古くなっています(期限切れ)

  • サーバーは、baseSecureRequestの一般的なonErrorResponse()でキャッチできるエラーコードまたはメッセージを返します。

  • このonError()では、LLTを使用してサーバーに新しいSLTを要求することにより、メモリ内のSLTを更新しようとするrefreshTokenRequest()オブジェクトを送信します。

  • refreshTokenRequestのonResponse()は、元の要求にコールバックして再送信できるようになりました。

  • ただし、onErrorResponse()は、接続エラーではない可能性があるため、おそらくすべてを放棄する必要があります。これは、無効なLLTによって引き起こされるエラーです。あなたが悪いLLTでリフレッシュしようとし続けるならば、あなたは決して出て行かないでしょう。
12
mjw
  1. AccountManager API in Android認証と承認に使用することをお勧めします。ブログをフォローすることもできます ここ
  2. OAuth 2.0サーバー側の実装については、IETFドラフトV2-31 ここ を読むことができます。
  3. OAuth 2.0の理解を深めるために、 Nitesh Kumarhere でブログを読むことができます。
  4. OAuth 2.0のサーバー側実装の場合、フォークできます Apis Autherization Server Githubのリポジトリ。
  5. その他の実装オプションは、OAuth 2.0 here のWebサイトにあります。
1
Gaurav Agarwal

このブログ投稿を見ましたか? https://smaspe.github.io/2013/06/06/volley-part2.html

Twitterトークンを使用するためにリクエストオブジェクトをオーバーライドする簡単な方法を示します。

@Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        Map<String, String> headers = new HashMap<String, String>();
        String auth = "Basic "
                + Base64.encodeToString((TwitterValues.CONSUMER_KEY 
                + ":" + TwitterValues.CONSUMER_SECRET).getBytes(),
                        Base64.NO_WRAP);
        headers.put("Authorization", auth);
        return headers;
    }
1
cbrulak

私の場合、次のように「基本」認証をトークン認証に変更しました。

@Override
public Map<String, String> getHeaders() throws AuthFailureError {
    Map<String,String> headers = new HashMap<>();
    //todo Esta es una authenticación basica (usuario y contraseña)
    /*String credentials = USER+":"+PASSWORD;
    String auth = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
    headers.put("Authorization", auth);*/
    //todo Esta es una authenticación con token (por tiempos)
    headers.put("Authorization", "Bearer" + " " + "tokenString");//App.getToken()
    return  headers;
}

私がしたことは、ログインをグローバル静的変数に保存して、それを使用できるようにすることでした。

0
Gerrard