0

私はMEANスタックを使用してREST APIを使用し、Passport JSを使用して認証を管理するアプリケーションで作業しています。ログインしているユーザーのためにGoogleに接続する(承認する)

認証では、バックエンドとフロントエンド間の通信にはJTWのトークンを使用します。トークンは、ローカルのユーザー名とパスワードに基づいて生成されます。

GoogleカレンダーAPIで使用するために、ユーザーのGoogleアカウントをプロフィールに追加(承認)したいと考えています。 (this->https://github.com/wanasit/google-calendarを使用)

私は既にGoogle認証ページにユーザーを送り、そこからトークンを取得することができました。問題は、ユーザーがページにリダイレクトされると、JWTトークンが失われてユーザーがその要求をチェックすることです。

現在ログインしているユーザーを取得する方法や、authorizeメソッドを呼び出すときにカスタムコールバック認証ヘッダー/ paramを渡す方法はありますか?

auth.js:

var googleParams = { 
     clientID: config.auth.google.clientID, 
     clientSecret: config.auth.google.clientSecret, 
     callbackURL: config.auth.google.callbackURL 
    } 
    var googleStrategy = new GoogleStrategy(googleParams, function (token, refreshToken, profile, done) { 
     profile.token = token; 
     return done(null, profile); 
    }); 

路線:

rotas.get(
    '/google', 
    auth.authenticate(), // will check the current user 
    auth.isLoggedIn, // make sure the user is really logged in 
    auth.authorize('google', { scope: googleScope, passReqToCallback: true }) // redirects to google to get the token 
); 

rotas.get('/callback/google', 
    auth.authorize('google', { scope: googleScope, passReqToCallback: true }) 
    auth.authRedirect() 
); 

上記auth.authRedirect()機能は私が見つけた最も近いソリューションです。これはユーザーが認証されているフロントエンドの既知のルートにユーザーをリダイレクトするExpressミドルウェアですが、必要なすべてのGoogleプロフィールと情報を取得することはできません...

答えて

1

されました:

  1. は、ユーザーのIDを取得します

  2. access_tokenはJWTを経由して要求を行ったユーザを認証し、stateオプションのプロパティに設定し

  3. ユーザーはGoogle認証ページにリダイレクトされ、接続したいアカウントを選択します

  4. (S)彼は今、私はちょうどそのIDを取得する必要があり、データベース内のユーザーを検索し、req.accountから、私は必要なデータを設定し、ユーザーのID

  5. を持つstateクエリのparamで私のコールバックURLにリダイレクトされますユーザーのopenidプロファイルが含まれています。

var googleScope = ['openid', 'email', 'https://www.googleapis.com/auth/calendar']; 
 

 
routes.get(
 
    '/google', 
 
    auth.authenticate(), 
 
    auth.isLoggedIn, 
 
    function (req, res, next) { 
 
     var _id = '' + req.user._id; // convert to String... _id is an mongoose object 
 
     return auth.authorize('google', { session: false, scope: googleScope, passReqToCallback: true, state: _id })(req, res, next) 
 
    } 
 
); 
 

 
routes.get('/callback/google', 
 
    function (req, res, next) { 
 
     auth.authorize('google', { session: false, scope: googleScope, passReqToCallback: true })(req, res, next); 
 
    }, 
 
    auth.saveUserData() 
 
);

saveUserData= function() { 
 
    return function (req, res, next) { 
 
     if (req.query.state) { 
 
      var _id = req.query.state; 
 
      User.findOne({ _id, deleted: false, active: true }) 
 
       .exec(function (err, user) { 
 
        if (err) { 
 
         res.send(err); 
 
        } 
 
        if (user) { 
 
         user.auth.google = { 
 
          id: req.account.id, 
 
          token: req.account.token, 
 
          email: (req.account.emails.length ? req.account.emails[0].value : null), 
 
          name: req.account.displayName 
 
         } 
 
         user.save(function (err, data) { 
 
          if (err) { 
 
           res.send(err); 
 
          } else { 
 
           res.redirect('/') 
 
          } 
 
         }) 
 
        } else { 
 
         res.sendStatus(401); 
 
        } 
 
       }) 
 
     } else { 
 
      res.sendStatus(400) 
 
     } 
 
    }

+0

うーん...いいね!私はこの 'state'プロパティを知らなかった。よくやった。 –

1

app.use(session)がルートの前に呼び出されていることを確認してください。

...

app.use(session({ 
    secret: 'secret' 
})) 

app.use(passport.initialize()) 
app.use(passport.session()) 

... 

rotas.get(
    '/google', 
    auth.authenticate(), // will check the current user 
    auth.isLoggedIn, // make sure the user is really logged in 
    auth.authorize('google', { scope: googleScope, passReqToCallback: true }) // redirects to google to get the token 
); 

rotas.get('/callback/google', 
    auth.authorize('google', { scope: googleScope, passReqToCallback: true }) 
    auth.authRedirect() 
); 

あなたreq.userは、この場合にはundefinedではありません。

正しく動作しない場合は、ここで作成したコード全体を配置できます。

希望すると助かります! :)私がやってしまったので、何

+0

私の知る限りでは、 '' 'passport.authorize'''と' '' passport.authenticate'''ですほとんど同じです...違いは、 '' 'authenticate''は' '' req.user''と '' 'authorize''が' 'req.account''を設定するということです。 それは私が実際にしようとしていることは、彼/彼女がすでに持っている資格情報を使用してユーザーを "再認証する"ことです。コールバックを "認証"して、 Googleのデータをローカルユーザープロファイルに保存するアカウントを承認します... –

+0

はい、私は試しましたが、私はまだGoogleから自動化を取得する要求をしたユーザーを取得できません。注:私はユーザーに "ログイン"しようとしていません...ちょうどローカルプロファイルにGoogleアカウントを接続して... –

+0

だから、あなたはすでにプロファイルデータを持っていますか?ログインしただけで、フロントエンドにプロファイルデータを送信したいのですが、そうですか?プロファイルデータ(Googleからのjwtトークン)を取得すると、自分のAPIにアクセスする権限をトークンに与えることができます。右? –

関連する問題