0

Ich habe eine E-Mail- und Kennwortstrategie mit JWT eingerichtet und möchte sie mit Google OAuth einrichten, anstatt einen Cookie zu verwenden.Erweitern einer OAuth2 Google Passport.js-Strategie für die Verwendung von JWT

Jetzt, während die beiden Google-Authentifizierungsrouten funktionieren, wird ein Benutzer in meiner Benutzer-Sammlung erstellt und ich werde zurück an die Callback-Route gesendet, ich bekomme undefiniert für den Benutzer, wenn ich versuche, zu gehen die Route/api/current_user.

Hier ist mein Code: irgendwelche Ideen?

index.js (Einspeisepunkt)

const express = require('express'); 
const http = require('http'); 
const bodyParser = require('body-parser'); 
const morgan = require('morgan'); 
const app = express(); 
const mongoose = require('mongoose'); 
const cors = require('cors'); 
const config = require('./config'); 
const passport = require('passport'); 
mongoose.connect(process.env.cosmosConn || config.conn); 
//App setup 
app.use(morgan('combined')); 
app.use(cors()); 
app.use(bodyParser.json({ type: '*/*' })); 
app.use(passport.initialize()); 
app.use(passport.session()); 
const router = require('./router'); 
router(app); 
//Server setup 
const port = process.env.port || process.env.PORT || 3090; 
const server = http.createServer(app); 
server.listen(port); 
console.log('Server listening on:', port); 

router.js

const Authentication = require('./controllers/authentication'); 
const passport = require('passport'); 
const User = require('./models/user'); 
const PlotCast = require('./models/plotCast'); 
const requireAuth = passport.authenticate('jwt', { session: true }); 
const requireSignin = passport.authenticate('local', { session: true }); 
const mongoose = require('mongoose'); 
mongoose.Promise = require('bluebird'); 
const passportService = require('./services/passport'); 

module.exports = function(app) { 
    app.get('/', 
     requireAuth, 
     (req, res) => 
     { 
      res.send({ 
       message: `Welcome to Trellis, ${req.user.email}! Here's what's going on with your plots:` 
      }); 
     }); 
    app.post('/signin', requireSignin, Authentication.signin); 
    app.post('/signup', Authentication.signup); 
    app.post('/confirmation', Authentication.confirmation); 
    app.post('/resend', Authentication.resend); 
    app.post('/verify-email', Authentication.verifyEmail); 
    app.post('/resend-verify-code', Authentication.resend); 
    app.post('/reset-password', Authentication.resetPassword); 
    app.post('/reset-password/verify', Authentication.verifyResetPassword); 
    app.post('/reset-password/new', Authentication.resetPasswordNew); 
    app.get('/plots', 
     requireAuth, 
     async (req, res) => 
     { 
      const user = await User.findOne({ email: req.user.email }).lean() 
      const company = user.company; 
      const plotcast = await PlotCast.find({ owner: company }).lean(); 
      if (!plotcast) { throw new Error('Plot Casts not found') } 
      else {res.send(plotcast); } 
     }); 
    app.get(
     '/auth/google', 
     passport.authenticate('google', { 
     scope: ['profile', 'email'] 
    }) 
    ); 
    app.get('/auth/google/callback', passport.authenticate('google')); 
    app.get('/api/current_user',(req, res) => 
    { 
     console.log(req); 
     res.send(req.user); 
    }) 

    app.get('/api/logout', (req, res) => 
    { 
     req.logout(); 
     res.send(req.user); 
    }) 
}; 

passport.js

const passport = require('passport'); 
const User = require('../models/user'); 
const JwtStrategy = require('passport-jwt').Strategy; 
const ExtractJwt = require('passport-jwt').ExtractJwt; 
const LocalStrategy = require('passport-local'); 
const GoogleStrategy = require('passport-google-oauth20').Strategy; 
const config = require('../config'); 

const localOptions = { usernameField: 'email' }; 
const localLogin = new LocalStrategy(localOptions, 
    async (email, password, done) =>{ 
     const existingUser = await User.findOne({ email: email }) 
     if (!existingUser) { return done(null, false); } 
     const passwordMatch = await existingUser.comparePassword(password); 
     if (!passwordMatch) { return done(null, false); } 
     return done(null, user); 
}); 

const jwtOptions = { 
    jwtFromRequest: ExtractJwt.fromHeader('authorization'), 
    secretOrKey: config.secret 
}; 

const jwtLogin = new JwtStrategy(jwtOptions, 
    async (payload, done) => 
    { 
     try 
     { 
      const user = await User.findById(payload.sub); 
      if (user) 
      { 
       done(null, user); 
      } else 
      { 
       done(null, false); 
      } 
     } 
     catch (e) 
     { 
      return done(e, false); 
     } 
}); 

passport.serializeUser((user, done) => 
{ 
    done(null, user.id); 
}); 

passport.deserializeUser(async (id, done) => 
{ 
    const user = await User.findById(id) 
    if(user){ done(null, user); } 
}); 

passport.use(new GoogleStrategy(
    { 
     clientID: config.googleClientID, 
     clientSecret: config.googleClientSecret, 
     callbackURL: '/auth/google/callback', 
     proxy: true 
    }, async (accessToken, refreshToken, profile, done) => 
    { 
     const existingUser = User.findOne({ googleId: profile.id }) 
     if (existingUser) 
     { 
      done(null, existingUser) 
     } else 
     { 
      const user = await new User({ googleId: profile.id }).save() 
      done(null, user); 
     } 
    } 
)); 

passport.use(jwtLogin); 
passport.use(localLogin); 

EDIT: refactored Code für Async/Await

Antwort

1

Sobald Google Ihren Rückruf erreicht Sie müssen das Token generieren und an den Benutzer senden. Möglicherweise möchten Sie den Benutzer (res.redirect) auf eine neue Route umleiten, die den Tokenaustausch abwickelt.

Mit anderen Worten, können Sie diese Logik innerhalb der Google-Callback-Funktion implementieren selbst:

app.get('/auth/google/callback', 
     passport.authenticate('google', { 
      //successRedirect: '/', 
      failureRedirect: '/' 
      , session: false 
     }), 
     function(req, res) { 
      var token = TokenService.encode(req.user); 
      res.redirect("/api?token=" + token); 
     }); 
Verwandte Themen