node.js - Passport 不会跨浏览器请求持续存在,与 Postman 一起使用 [英] node.js - Passport not persisting across browser requests, works with Postman

查看:14
本文介绍了node.js - Passport 不会跨浏览器请求持续存在,与 Postman 一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在使用 create-react-app 样板,并且一直在尝试添加 auth.我使用 axios 作为我的基于承诺的带有 React.js 的 HTTP 库.我一直在后端使用带有快递、快递会话、护照和护照本地的节点.

I am currently using the create-react-app boiler plate and have been attempting to add auth. I am using axios as my promise based HTTP libray with React.js. I have been using node with express, express-session, passport and passport-local on the backend.

这是我的 server.js 文件,有一些例外:

Here is my server.js file with some exlusions:

const express = require('express');
const mysql = require('mysql');
const app = express();
const cors = require('cors');
const session = require('express-session');
const passport = require('passport');
const morgan = require('morgan');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const LocalStrategy = require('passport-local').Strategy;

// Express only serves static assets in production
if (process.env.NODE_ENV === 'production') {
  app.use(express.static('client/build'));
}

app.set('port', (process.env.PORT || 3001));

app.use(cors({
  credentials: true,
  origin: 'http://localhost:3000'
}));
app.use(morgan('dev'));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cookieParser());
app.use(session({
  secret: 'topsecretpassword',
  resave: true,
  saveUninitialized: false,
  cookie: {
    path: '/',
    originalMaxAge: 1000 * 60 * 60 * 24,
    httpOnly: true,
    secure: false
  }
}));
app.use(passport.initialize());
app.use(passport.session());


// Setup Database connection
const connection = mysql.createConnection({
  host : 'localhost',
  user : 'root',
  password : '',
  database : 'mvy_db'
});

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

passport.deserializeUser(function(user, done) {
  connection.query('SELECT * FROM users WHERE id=?', user, function(err, userId) {
    if (err) {
      res.status(400).json({
        error: 'Database Error',
        id: userId[0]
      });
    }

    done(err, userId[0]);
  });
});

passport.use(new LocalStrategy({
  usernameField: 'email',
  passwordField: 'password',
  },
  function(email, password, done) {
    connection.query('SELECT * FROM users WHERE email=?', email, function(err, user) {
      if (err) {
        return done(err);
      }
      if (!user.length) {
        return done(null, false, { message: 'Incorrect email.' });
      }
      if (user[0].password !== password) {
        return done(null, false, { message: 'Incorrect password.' });
      }
      return done(null, user[0]);
    });
  }
));

app.post('/signin', passport.authenticate('local'), function(req, res) {
  console.log(req.session);
  return res.send('login success!');
});

function isAuthenticated (req,res,next){
  console.log(req.session);
  if(req.session.passport.user)
     return next();
  else
     return res.status(401).json({
       error: 'User not authenticated'
     })

}

app.get('/checkauth', isAuthenticated, function(req,res) {
  res.status(200).json({
    status: 'User Authenticated!'
  });
})

app.get('/signout', function(req,res) {
  req.session.destroy();
  res.status(200).json({ success: 'successfully signed out' });
})

使用邮递员(甚至在浏览器上),我能够成功登录并且以下内容保存在 req.session 对象中:

Using postman (and even on the browser), I am able to successfully login and the following is held in the req.session object :

   cookie:
    { path: '/',
      _expires: null,
      originalMaxAge: 86400000,
      httpOnly: true,
      secure: false },
      passport: { user: 1 } }

我使用 axios 的登录请求:

my login request using axios:

return axios.post(ROOT_URL + 'signin', {
      email: e.target.email.value,
      password: e.target.password.value
    }).then((response) => {
      if (response.status === 200) {
        console.log(response);
      }
    })

我使用 axios 的 checkAuth 请求(这是我返回 500 错误的地方):

My checkAuth request using axios (this is where I get a 500 error returned):

  axios.get(ROOT_URL + 'checkauth', { withCredentials: true })
    .then((response) => {
      if (response.status === 200) {
        return true;
      } else {
        return false;
      }
    });

错误信息前检查认证后的req.session对象,注意passport对象不存在了:

The req.session object after checking authentication before the error message, note that the passport object doesn't exist anymore:

 Session {
   cookie:
    { path: '/',
      _expires: null,
      originalMaxAge: 86400000,
      httpOnly: true,
      secure: false } }

这是我在尝试检查用户是否获得授权时在控制台上收到的错误消息:

This is the error message I get on the console when I attempt to check that the user is authorized:

 TypeError: Cannot read property 'user' of undefined
     at isAuthenticated (/server.js:94:26)

我已经敲了几个小时的头,试图解决这个问题.我认为这可能与 CORS 有关,但经过数小时的研究后,情况似乎并非如此.它仍然有可能是 CORS 问题,但真正让我感到困惑的是它与 Postman 一起工作得很好,但在我的 Chrome 浏览器上却没有.任何帮助表示赞赏!

I've been banging my head for hours, trying to resolve this issue. I thought it might have something to do with CORS, but after hours of playing around with it that doesn't seem to be the case. It's still plausible that it's a CORS issue, but what's really flustering me is that it works full well with Postman but not on my Chrome browser. Any help is appreciated!

推荐答案

好的,我找到了解决我的问题的方法.这似乎是 axios 和我的 get 请求配置的问题.出于某种原因,使用结构 axios.get(URL) .then(response) 不适用于 withCredentials 属性.

Alright, so I found the solution to my problem. It appeared to be an issue with axios and the configuration of my get requests. For some reason, using the structure axios.get(URL) .then(response) doesn't work with the withCredentials property.

相反,我必须将我的请求发送为:

Instead, I had to send my request as:

axios(ROOT_URL + 'checkauth', {方法:'获取',withCredentials: 真}).then((响应) => {如果(响应.状态 === 200){返回真;} 别的 {返回假;}});

这篇关于node.js - Passport 不会跨浏览器请求持续存在,与 Postman 一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆