Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinite authentication loop on protected route #1142

Open
2 tasks done
HenriqueMentormate opened this issue May 12, 2024 · 4 comments
Open
2 tasks done

Infinite authentication loop on protected route #1142

HenriqueMentormate opened this issue May 12, 2024 · 4 comments

Comments

@HenriqueMentormate
Copy link

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Fastify version

4.27.0

Plugin version

2.4.0

Node.js version

20.11.1

Operating system

macOS

Operating system version (i.e. 20.04, 11.3, 10)

14.4.1

Description

Hello. I am trying to use passport-microsoft and my issue is that after I have been authenticated and the callback URL has been reached and I am redirected to the protected route '/', I get prompted to log in again, this happens over and over again.

Here's an MRE:

"use strict";

const { readFileSync } = require("fs");
const { join } = require("path");

const fastify = require("fastify")({ logger: true });

const passport = require("@fastify/passport");
const secureSession = require("@fastify/secure-session");
const { Strategy: MicrosoftStrategy } = require("passport-microsoft");

const PORT = 3000;
const BASE_URL = "http://localhost";
const CLIENT_ID = "...";
const CLIENT_SECRET = "...";
const CALLBACK = `${BASE_URL}:${PORT}/microsoft/callback`;

// --- plugins (from the Fastify ecosystem) ---
fastify.register(secureSession, {
  key: readFileSync(join(__dirname, "secret-key")),
});
fastify.register(passport.initialize());
fastify.register(passport.secureSession());

passport.use(
  "microsoft",
  new MicrosoftStrategy(
    {
      clientID: CLIENT_ID,
      clientSecret: CLIENT_SECRET,
      callbackURL: CALLBACK,
      scope: ["user.read"],
    },
    function (accessToken, refreshToken, profile, done) {
      done(null, profile);
    }
  )
);
passport.registerUserSerializer(async (user) => user.id);
passport.registerUserDeserializer(async (user) => user);

// --- routes                               ---
const defRoutes = [
  {
    method: "GET",
    url: `/auth/login`,
    preValidation: passport.authenticate("microsoft", {
      authInfo: false,
    }),
    handler: (req, res, err, user, status) => {},
  },
  {
    method: "GET",
    url: `/microsoft/callback`,
    preValidation: passport.authenticate("microsoft", {
      authInfo: false,
      successRedirect: "/",
    }),
    handler: (req, res) => {},
  },
  {
    method: "GET",
    url: `/`,
    preValidation: passport.authenticate("microsoft", { authInfo: false }),
    handler: (req, res) => {
      return res.send(req.user);
    },
  },
];

// Add all routes into Fastify route system
for (const route of defRoutes) {
  fastify.route(route);
}

async function start() {
  try {
    fastify.listen({ port: PORT });
  } catch (e) {
    throw e;
  }
}

start();

I am not sure if I am missing anything or what the issue is.

Link to code that reproduces the bug

No response

Expected Behavior

I am not prompted to log in again when redirected to the '/' route

@mcollina
Copy link
Member

Thanks, I've never used passport-microsoft, so I can't really help here.

@HenriqueMentormate
Copy link
Author

HenriqueMentormate commented May 13, 2024

Something similar happens with passport-google-oauth20, so it does not seem to be a passport-microsoft only

MRE:

"use strict";

const { readFileSync } = require("fs");
const { join } = require("path");

const fastify = require("fastify")({ logger: true });

const passport = require("@fastify/passport");
const secureSession = require("@fastify/secure-session");
const { Strategy: GoogleStrategy } = require("passport-google-oauth20");

const PORT = 3000;
const BASE_URL = "http://localhost";
const CLIENT_ID = "...";
const CLIENT_SECRET = "...";
const CALLBACK = `${BASE_URL}:${PORT}/google/callback`;

// --- plugins (from the Fastify ecosystem) ---
fastify.register(secureSession, {
  key: readFileSync(join(__dirname, "secret-key")),
});
fastify.register(passport.initialize());
fastify.register(passport.secureSession());

passport.use(
  "google",
  new GoogleStrategy(
    {
      clientID: CLIENT_ID,
      clientSecret: CLIENT_SECRET,
      callbackURL: CALLBACK,
      scope: ['email', 'profile'],
    },
    function (accessToken, refreshToken, profile, done) {
      done(null, profile);
    }
  )
);
passport.registerUserSerializer(async (user) => user.id);
passport.registerUserDeserializer(async (user) => user);

// --- routes                               ---
const defRoutes = [
  {
    method: "GET",
    url: `/auth/login`,
    preValidation: passport.authenticate("google", {
      authInfo: false,
    }),
    handler: (req, res, err, user, status) => {},
  },
  {
    method: "GET",
    url: `/google/callback`,
    preValidation: passport.authenticate("google", {
      authInfo: false,
      successRedirect: "/",
    }),
    handler: (req, res) => {},
  },
  {
    method: "GET",
    url: `/`,
    preValidation: passport.authenticate("google", { authInfo: false }),
    handler: (req, res) => {
      return res.send(req.user);
    },
  },
];

// Add all routes into Fastify route system
for (const route of defRoutes) {
  fastify.route(route);
}

async function start() {
  try {
    fastify.listen({ port: PORT });
  } catch (e) {
    throw e;
  }
}

start();

@linuswillner
Copy link

linuswillner commented May 21, 2024

I'm having this same issue with passport-discord-auth as well. If I decorate any route with { preValidation: passport.authenticate('discord') }, it just tosses me back to Discord to authenticate again even though I was just there. In my callback route, I can redirect to some route, and Fastify tells me the browser asks for that route, but then Passport just sends the browser back into authentication again.

@Jerome1337
Copy link

passport-oauth2 have the behavior 🫤

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants