0
votes

What should I do to get req.user and req.logout and all the requests created in passport middleware in ApolloServer context. Just like I have access to it in

app.get('/good', isLoggedIn, (req, res) => res.send(req.user));

I use cookie-session, paspport, passport-google-oauth20, express, apollo-server, express and cors packages

app.use(
  cors({
    origin: "http://localhost:3000",
    credentials: true
  })
);

app.use(cookieSession({
  name: 'session',
  keys: ['key1', 'key2']
}))

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

app.get('/auth/google', passport.authenticate('google', { scope: ['profile','email'] }));
app.get('/auth/google/callback', passport.authenticate('google', {
  successRedirect: '/good',
  failureRedirect: '/fail',
}));


app.get('/good', (req, res) => res.send(req.user));

// route for logging out
app.get('/logout', (req, res) => {
  req.session = null;
  req.logout();
  res.redirect('/');
  });


// Connect to Mongo(skipped)

const { ApolloServer } = require('apollo-server-express');

const typeDefs = require('./modules/graphqlschemas/index');
const resolvers = require('./modules/resolvers/index');


// #5 Initialize an Apollo server
const server = new ApolloServer({ 
  typeDefs: typeDefs,
  resolvers: resolvers,
  context: ({ req }) => ({
    getUser: () => {
      console.log(req.user);  // ! undefined !
    },
    logout: () => req.logout() // ! header not sent to the client error !
  })
});

Here's my googleAuth file:

const GoogleStrategy = require('passport-google-oauth20').Strategy
const passport = require('passport');
const User = require('../models/user');

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

passport.deserializeUser((id, done) => {
  User.findById(id, (err, user) => done(err, user))
})
  
passport.use(
    new GoogleStrategy(
      {
        clientID: process.env.GOOGLE_CLIENT_ID,
        clientSecret: process.env.GOOGLE_CLIENT_SECRET,
        callbackURL: '/auth/google/callback',
        proxy: true
      },
      async (accessToken, refreshToken, profile, done) => {
        const newUser = {
          googleId: profile.id,
          displayName: profile.displayName,
          firstName: profile.name.givenName,
          lastName: profile.name.familyName,
          image: profile.photos[0].value,
        }

        try {
          let user = await User.findOne({ googleId: profile.id })

          if (user) {
            done(null, user)
          } else {
            user = await User.create(newUser)
            done(null, user)
          }
        } catch (err) {
          console.error(err)
        }
      }
    )
  )
2
It's not clear from the code away where you're calling applyMiddleware. It should be done after you add your session middleware.Daniel Rearden
Whatever, the problem was that ind graphql playground settings, credentials was set on omit by default. I just needed to change it. Look here stackoverflow.com/questions/51977753/… or directly here i.stack.imgur.com/D7OU3.pngWiktor Kujawa

2 Answers

0
votes

You can inject req.user into Apollo's context by creating a middleware for it after authentication with passport is done

/// app.js

// you can move this to a new module for code brevity
const strategy = new GoogleStrategy(
      {
        clientID: process.env.GOOGLE_CLIENT_ID,
        clientSecret: process.env.GOOGLE_CLIENT_SECRET,
        callbackURL: '/auth/google/callback',
        proxy: true
      },
      async (accessToken, refreshToken, profile, done) => {
        const newUser = {
          googleId: profile.id,
          displayName: profile.displayName,
          firstName: profile.name.givenName,
          lastName: profile.name.familyName,
          image: profile.photos[0].value,
        }

        try {
          let user = await User.findOne({ googleId: profile.id })

          if (user) {
            done(null, user)
          } else {
            user = await User.create(newUser)
            done(null, user)
          }
        } catch (err) {
          console.error(err)
        }
      }
    )

passport.use(strategy)


// ...

const app = express()

// ...

passport.initialize()

app.use('/graphql', (req, res, next) => {
  passport.authenticate('google', { scope: ['profile','email'] }, (err, user, info) => {
    if (user) {
      req.user = user
    }

    next()
  })(req, res, next)
})

// ...
const typeDefs = require('./modules/graphqlschemas/index');
const resolvers = require('./modules/resolvers/index');

const server = new ApolloServer({
  typeDefs: typeDefs,
  resolvers: resolvers,
  context: ({ req }) => {
   // do some other things with req

   // inject data into context like user
   return { user: req.user }
  }
})

server.applyMiddleware({
  app
})
0
votes

Whatever, the problem was that in graphql playground settings, credentials was set on omit by default. I just needed to change it. Look here Apollo 2.0.0 Graphql cookie session or directly here i.stack.imgur.com/D7OU3.png