28

Passport.js を使用して認証を行っています。Google の OAuth2 ドキュメント に従って、状態変数を渡しています。

app.get('/authenticate/googleOAuth', function(request, response) {
  passport.authenticate('google', {
    scope:
    [
      'https://www.googleapis.com/auth/userinfo.profile',
      'https://www.googleapis.com/auth/userinfo.email'
    ],
    state: { blah: 'test' }
  })(request, response);
});

ただし、後日その変数にアクセスできないようです。

passport.use(new googleStrategy(
{
    clientID: '...',
    clientSecret: '...',
    callbackURL: '...',
    passReqToCallback: true
},
function(request, accessToken, refreshToken, profile, done) {
  console.log('state: ' + request.query.state);
  login(profile, done);
}));

request.query.state は未定義です。request.param("state") も機能しません。

認証コールバック後にその変数を取得するにはどうすればよいですか?

4

2 に答える 2

25

これが機能しない理由は、状態を文字列ではなくオブジェクトとして渡しているためです。パスポートはその値を文字列化していないようです。状態パラメーターを介してオブジェクトを渡したい場合は、次のようにすることができます。

passport.authenticate("google", {
  scope: [
    'https://www.googleapis.com/auth/userinfo.profile',
    'https://www.googleapis.com/auth/userinfo.email'
  ],
  state: base64url(JSON.stringify(blah: 'test'))
})(request, response);

Rob DiMarco が回答で指摘したように、コールバックオブジェクトのstateparam にアクセスできます。req.query

ただし、アプリケーションの状態をエンコードしてパラメーターに渡すことはstate良い考えではありません。OAuth 2.0 RFCセクション 4.1.1では、状態を「不透明な値」と定義しています。CSRF 保護に使用するためのものです。認可リクエストとコールバックの間でアプリケーションの状態を保持するためのより良い方法は、次のようにすることです。

  1. いくつかのパラメータ値を生成しstateます (たとえば、Cookie のハッシュ)
  2. state認可リクエストを開始する前に、アプリケーションの状態を識別子として永続化します
  3. stateGoogle から返されたパラメータを使用して、コールバック リクエスト ハンドラでアプリケーションの状態を取得します
于 2014-04-21T16:56:13.663 に答える
1

Node.js v0.8.9 を使用してこれを簡単にテストすると、Google OAuth 2.0 認証要求のランタイム構成パラメーターは、最終的にライブラリーのgetAuthorizeUrlメソッドを介してフォーマットされnode-authます。querystring.stringifyこのメソッドは、リダイレクト URL のフォーマットに依存しています。

exports.OAuth2.prototype.getAuthorizeUrl= function( params ) {
  var params= params || {};
  params['client_id'] = this._clientId;
  params['type'] = 'web_server';
  return this._baseSite + this._authorizeUrl + "?" + querystring.stringify(params);
}

(上記はhttps://github.com/ciaranj/node-oauth/blob/efbce5bd682424a3cb22fd89ab9d82c6e8d68caa/lib/oauth2.js#L123からコピー)。

指定した状態パラメーターを使用してコンソールでテストします。

querystring.stringify({ state: { blah: 'test' }})=>'state='

回避策として、オブジェクトを JSON エンコードするか、単一の文字列を使用することで、問題を解決できます。stateその後、コールバック リクエスト ハンドラで を介して にアクセスできますreq.query.state。アクセスするJSON.parse(req.query.state)ときは注意してください。

于 2013-01-15T06:20:31.890 に答える