为什么我要么丢失状态值(并且访问被拒绝),要么无法重定向回原始网址?

问题描述 投票:0回答:1

所以,在阅读了我的 stackoverflow 帖子、auth0 社区帖子并尝试了多种想法后,我仍然感到困惑。

我有一个nodejsexpress应用程序(和rest api)运行了很多年,但从来没有工作过的一件事(并且我一直在忍受)是,如果用户访问我用中间件保护的url登录后它总是重定向回网站的根目录,而不是请求的网址。

我想说我已经将问题范围缩小到了某个特定区域,但我不确定我已经做到了;

无论如何; 我的 app.js 文件中有所有常用设置:

var strategy = new Auth0Strategy(
      {
        domain: process.env.AUTH0_DOMAIN,
        clientID: process.env.AUTH0_CLIENTID,
        clientSecret: process.env.AUTH0_CLIENT_SECRET,
        callbackURL: process.env.AUTH0_CALLBACK_URL || 'http://127.0.0.1:3000/callback'
      },
      function (accessToken, refreshToken, extraParams, profile, done) {
        // accessToken is the token to call Auth0 API (not needed in the most cases)
        // extraParams.id_token has the JSON Web Token
        // profile has all the information from the user
        return done(null, profile);
      }
    );

    passport.use(strategy);
    
    

    // You can use this section to keep a smaller payload
    passport.serializeUser(function (user, done) {
      done(null, user);
    });

    passport.deserializeUser(function (user, done) {
      done(null, user);
    });

    // config express-session
    var sess = {
      secret: 'ThisisMySecret',
      cookie: {
        httpOnly:false,
        secure:false
      },
      resave: false,
      saveUninitialized: false
    };
    if (app.get('env') === 'prod') {
      console.log("prod environment")
      app.set('trust proxy', 1); // trust first proxy
      sess.cookie.secure = true; // serve secure cookies, requires https
      sess.proxy = true;
      // console.log("session:sess");
      // console.log(sess);
    }  

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

登录路径:

router.get('/login', function(req, res, next) {
      req.session.returnTo = req.query.returnTo; // Store the returnTo value in session
      console.log("inside login route: " + req.session.returnTo)
      const state = uuidv4(); 
      passport.authenticate('auth0', {
        scope: 'openid email profile',
        state: state // Pass the returnTo value as the state parameter
      })(req, res, next);
    });

回调路线:

router.get('/callback', function(req, res, next) {
      console.log("inside callback route: " + req.session.returnTo)
      passport.authenticate('auth0', function(err, user, info) {
        console.log("inside callback authenticate function: " + req.session.returnTo)
        console.log(user)
        console.log(info)
        if (err) { return next(err); }
        if (!user) {
          console.log(user)
          console.log(info)
          res.render('beta/failed-login', {
            static_path:'/static',
            theme:process.env.THEME || 'flatly',
            pageTitle : "Access Denied",
            pageDescription : "Access Denied",
            query:req.query
          });
        } else {
          req.logIn(user, function (err) {
            if (err) {console.log(err); return next(err); }
            console.log("inside callback route: " + req.session.returnTo)
            console.log("user inside callback route: " + user)
            const returnTo = req.session.returnTo || '/'; // Retrieve the returnTo value from session
            delete req.session.returnTo; // Remove the returnTo value from session
            res.redirect(returnTo);
          });
        }
      })(req, res, next);
    });

一些中间件:

 function secured(req, res, next) {
      if (req.isAuthenticated()) {
        return next();
      }
      console.log("query in middleware: " + req.query.state)
      console.log("originalUrl in middleware: " + req.originalUrl)
      const returnTo = req.query.state || req.originalUrl;
      req.session.returnTo = returnTo; // Store the returnTo value in session
      console.log("returnTo in middleware: " + returnTo)
      console.log("session.returnTo in middleware: " + req.session.returnTo)
      res.redirect('/login?returnTo=' + encodeURIComponent(returnTo));
    }

以及一个受保护路由示例(很多):

 router.get('/user', secured,async function (req, res) {
      const { _raw, _json, userProfile } = req.user;
      console.log(req.user)
      res.render('beta/user', {
        userProfile: JSON.stringify(userProfile, null, 2),
        static_path:'/static',
        theme:process.env.THEME || 'flatly',
        pageTitle : "User Profile",
        pageDescription : "User Profile",
      });
    });

当我访问 /user 时,我会在日志中看到以下内容

Server running at http://127.0.0.1:3000/
query in middleware: undefined
originalUrl in middleware: /user
returnTo in middleware: /user
session.returnTo in middleware: /user
inside login route: /user
inside callback route: /user
inside callback authenticate function: /user
false
{ message: 'Unable to verify authorization request state.' }
false
{ message: 'Unable to verify authorization request state.' }

我发现如果我删除

state: state // Pass the returnTo value as the state parameter

从传递到 /login 路由中的 Passport.authenticate 调用的对象中,登录可以工作,但现在它不会重定向..

所以我很困惑,我在本地环境和 Heroku 上托管的生产环境中都遇到了这种行为(不确定这是否相关..)我希望这只是与 https 相关的本地构建问题,但我还没有还没有在本地进行配置,但我的 heroku 版本已设置为 https (https://stockport-badminton.co.uk)

我还注意到,当它在 auth0 日志中失败时,我看到登录成功,但没有成功交换授权码。

有什么想法吗?

node.js express session redirect auth0
1个回答
0
投票

也许不是这样的答案,而是意识到我错过了一些明显的东西(或者也许我的解决方案是一个安全漏洞......)

如上所述 - 回调路由没有重定向信息。

所以 - 我只是在全局级别编写了一个新变量并写入该变量..该变量可用于所有路线,现在它可以工作了。

© www.soinside.com 2019 - 2024. All rights reserved.