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

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

问题描述

我目前正在使用create-react-app样板,并且一直在尝试添加auth.我使用axios作为React.js的基于我的Promise的HTTP libray.我一直在后端使用具有express,express-session,passport和本地Passport的节点.

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对象,请注意,护照对象不再存在:

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', { method: 'get', withCredentials: true }) .then((response) => { if (response.status === 200) { return true; } else { return false; } });

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

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

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