Node JS Authentication With Google OAuth and Github

 Perfect 👍 Let’s extend your Passport + PostgreSQL + JWT setup with Google and GitHub OAuth.

That way, you’ll be ready if the company asks for social login in your Node.js exam.


📝 Steps for Google & GitHub OAuth

1. Install OAuth Strategies

npm install passport-google-oauth20 passport-github2

2. Update Passport Config (config/passport.js)

const { Strategy: LocalStrategy } = require("passport-local");
const { Strategy: JwtStrategy, ExtractJwt } = require("passport-jwt");
const GoogleStrategy = require("passport-google-oauth20").Strategy;
const GitHubStrategy = require("passport-github2").Strategy;
const bcrypt = require("bcryptjs");
const User = require("../models/User");

module.exports = (passport) => {
  // ✅ Local Strategy
  passport.use(
    new LocalStrategy({ usernameField: "email" }, async (email, password, done) => {
      try {
        const user = await User.findOne({ where: { email } });
        if (!user) return done(null, false, { message: "User not found" });

        const isMatch = await bcrypt.compare(password, user.password);
        if (!isMatch) return done(null, false, { message: "Wrong password" });

        return done(null, user);
      } catch (err) {
        return done(err);
      }
    })
  );

  // ✅ JWT Strategy
  passport.use(
    new JwtStrategy(
      {
        jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
        secretOrKey: process.env.JWT_SECRET,
      },
      async (jwtPayload, done) => {
        try {
          const user = await User.findByPk(jwtPayload.id);
          if (user) return done(null, user);
          return done(null, false);
        } catch (err) {
          return done(err, false);
        }
      }
    )
  );

  // ✅ Google OAuth Strategy
  passport.use(
    new GoogleStrategy(
      {
        clientID: process.env.GOOGLE_CLIENT_ID,
        clientSecret: process.env.GOOGLE_CLIENT_SECRET,
        callbackURL: "/api/auth/google/callback",
      },
      async (accessToken, refreshToken, profile, done) => {
        try {
          const [user] = await User.findOrCreate({
            where: { email: profile.emails[0].value },
            defaults: {
              name: profile.displayName,
              password: "google-oauth", // placeholder
            },
          });
          return done(null, user);
        } catch (err) {
          return done(err, false);
        }
      }
    )
  );

  // ✅ GitHub OAuth Strategy
  passport.use(
    new GitHubStrategy(
      {
        clientID: process.env.GITHUB_CLIENT_ID,
        clientSecret: process.env.GITHUB_CLIENT_SECRET,
        callbackURL: "/api/auth/github/callback",
      },
      async (accessToken, refreshToken, profile, done) => {
        try {
          const [user] = await User.findOrCreate({
            where: { email: profile.emails[0].value },
            defaults: {
              name: profile.username,
              password: "github-oauth", // placeholder
            },
          });
          return done(null, user);
        } catch (err) {
          return done(err, false);
        }
      }
    )
  );
};

3. Add Routes (routes/authRoutes.js)

const express = require("express");
const passport = require("passport");
const jwt = require("jsonwebtoken");

const router = express.Router();

// ✅ Google OAuth
router.get("/auth/google", passport.authenticate("google", { scope: ["profile", "email"] }));

router.get(
  "/auth/google/callback",
  passport.authenticate("google", { session: false }),
  (req, res) => {
    const token = jwt.sign({ id: req.user.id }, process.env.JWT_SECRET, { expiresIn: "1h" });
    res.json({ token, user: req.user });
  }
);

// ✅ GitHub OAuth
router.get("/auth/github", passport.authenticate("github", { scope: ["user:email"] }));

router.get(
  "/auth/github/callback",
  passport.authenticate("github", { session: false }),
  (req, res) => {
    const token = jwt.sign({ id: req.user.id }, process.env.JWT_SECRET, { expiresIn: "1h" });
    res.json({ token, user: req.user });
  }
);

module.exports = router;

4. Environment Variables (.env)

DB_NAME=userdb
DB_USER=postgres
DB_PASS=yourpassword
DB_HOST=localhost
JWT_SECRET=supersecretkey

GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret

GITHUB_CLIENT_ID=your_github_client_id
GITHUB_CLIENT_SECRET=your_github_client_secret

👉 You get these OAuth credentials from:


5. Test in Browser / Postman

  • Google:
    http://localhost:3000/api/auth/google → redirects → callback → returns JWT

  • GitHub:
    http://localhost:3000/api/auth/github → redirects → callback → returns JWT


✅ What You Now Have

  • Local login with email & password

  • JWT-protected routes

  • Social login with Google + GitHub OAuth

  • All users stored in Postgres


Do you want me to also prepare a short flow diagram (Google/GitHub OAuth → Passport → JWT → API access) so you can explain clearly in your exam?



Great 👍 here’s a short flow diagram you can use to explain Google/GitHub OAuth with Passport + JWT + API access in your exam.


🔄 OAuth Authentication Flow

[ User ] 
   │ clicks "Login with Google/GitHub"
   ▼
[ Client App / Browser ]
   │ redirects to Google/GitHub login page
   ▼
[ Google / GitHub OAuth Server ]
   │ user approves access
   ▼
[ OAuth Callback (Passport Strategy) ]
   │ Passport verifies user profile
   │ If new → create user in Postgres
   │ If existing → fetch from Postgres
   ▼
[ Node.js Backend ]
   │ generates JWT token (user.id inside)
   ▼
[ Client App ]
   │ stores JWT (localStorage / cookie)
   ▼
[ API Requests ]
   │ sends "Authorization: Bearer <token>"
   ▼
[ Passport JWT Strategy ]
   │ verifies token with secret key
   │ fetches user from Postgres
   ▼
[ Protected Routes / Profile API ]
   → Success: return user data
   → Failure: 401 Unauthorized

✅ Key Talking Points for Exam

  • Passport Strategies: Local (email/password), Google, GitHub.

  • Callback: After OAuth success, Passport gets user profile.

  • Database: Store user (if new) or fetch existing one in PostgreSQL.

  • JWT: After login, backend issues JWT → client uses it for all API calls.

  • Passport-JWT Strategy: Protects routes by verifying tokens.


Would you like me to also create a ready-to-use slide-style diagram image (visual boxes + arrows) so you can show in interview/exam instead of just text?

Previous Post Next Post