0

Je travaille dans une application qui utilise une API REST en utilisant la pile MEAN et Passport JS pour gérer l'authentification.Rest API pour connecter (autoriser) google pour utilisateur connecté

L'authentification, nous utilisons JTW jetons pour la communication entre le backend et le frontend. Le jeton est généré en fonction du nom d'utilisateur local et des mots de passe.

Maintenant je veux ajouter (autoriser) le compte google de l'utilisateur au profil à utiliser avec google calendar API. (en utilisant ce->https://github.com/wanasit/google-calendar)

J'ai déjà réussi à envoyer l'utilisateur à la page d'autorisation google, et à récupérer le jeton. Le problème est que lorsque l'utilisateur est redirigé vers la page, il perd le jeton JWT où je vérifie l'utilisateur pour la demande.

Existe-t-il un autre moyen d'obtenir l'utilisateur actuellement connecté ou de passer un en-tête/param d'autorisation de rappel personnalisé lors de l'appel de la méthode authorize?

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); 
    }); 

itinéraires:

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() 
); 

la fonction auth.authRedirect() ci-dessus est la solution la plus proche que j'ai trouvé. C'est un middleware Express qui redirige l'utilisateur vers un itinéraire connu dans le frontend où l'utilisateur est authentifié ... mais je ne serais pas en mesure de récupérer tout son profil Google et les informations dont j'ai besoin ...

Répondre

1

Alors ce que je fini par faire était:

  1. Authentifier l'utilisateur qui fait la demande par JWT access_token

  2. Obtenir l'ID de l'utilisateur et le mettre à la propriété de l'option state

  3. L'utilisateur est redirigé vers la page d'autorisation google et choisit le (s) compte (s) qu'il souhaite connecter

  4. (S) Il est redirigé vers l'URL de mon rappel au Maintenant, je viens de param de requête state ayant l'identifiant de l'utilisateur

  5. pour obtenir cet identifiant, recherchez l'utilisateur dans la base de données et définir les données dont j'ai besoin req.account qui contient le profil openid de l'utilisateur.

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

Hmm ... bien! Je ne connaissais pas cette propriété 'state'. Bien joué. –

1

Vous devez assurez-vous que le app.use(session) a été appelé avant toute route.

...

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() 
); 

Votre req.user ne sera pas undefined dans ce cas.

Si cela ne fonctionne pas correctement, je peux mettre tout mon code que j'ai créé ici.

J'espère que cela vous aidera! :)

+0

pour autant que je sache, '' 'passport.authorize''' et' '' passport.authenticate''' sont presque identique ... la différence est que le '' 'authenticate''' définira' '' 'req.user''' et' '' authorize''' définit '' 'req.account''' Vous ne savez pas si c'est clair sur la question, mais ce que je cherche vraiment à faire est de "réauthentifier" l'utilisateur en utilisant les informations d'identification qu'il/elle a déjà .. comme, passer un paramètre afin que je puisse "authentifier" le rappel, obtenir l'utilisateur et " autoriser "le compte, en enregistrant les données google sur le profil de l'utilisateur local ... –

+0

oui, j'ai essayé, mais je n'arrive toujours pas à obtenir l'utilisateur qui a fait la demande pour obtenir l'autorisation de google. Note: Je n'essaie pas de "connecter" l'utilisateur ... il suffit de connecter le compte google au profil local ... –

+0

Donc, vous avez déjà les données de profil, non? Vous venez de vous connecter et vous voulez envoyer les données de profil à votre frontal, n'est-ce pas? Et une fois que vous avez les données de profil (et le jeton jwt de google), vous voulez pouvoir être autorisé à accéder à votre propre API (avec token). Droite? –