【问题标题】:req.isAuthenticated() in express and passport-local returns falsereq.isAuthenticated() 在 express 和 passport-local 中返回 false
【发布时间】:2020-02-09 08:16:20
【问题描述】:

我希望有人能对我的情况有所了解。 req.isAuthenticated() 在通过 fetch API 在 app.router 端点(在端口 3001 中运行)调用后总是返回 false。看来,当我执行 req.isAuthenticated()

时,connect.sid 未成功传递到 req arg

另一方面,我的 react 开发服务器运行在 3000 端口

这是我目前的设置。

Login Route,验证用户名和密码,并通过cookie值返回connect.sid。

const express           = require('express')
const router            = express.Router()
const passport          = require('passport')
...
router.post( '/authenticate', passport.authenticate('local'), ( req, res, next ) => {
    res.status( 200 ).json({
        'response': 'Welcome User',
        'redirect' : '/dashboard'
    })
})
...
module.exports = router

此时,我的用户路由应该能够访问受保护的路由。它只是返回数据库上的所有用户。

const express           = require('express')
const router            = express.Router()
const SimpleCmsUsers    = require('../models/Users.models.js')
const authPassportLocal = require('../passport/auth.PassportLocal.js') 
...
router.get( '/', authPassportLocal ,( req, res, next ) => {
    console.log( req.headers )
    console.log( req.body )

    SimpleCmsUsers
    .find({})
    .then(( users ) => {
        return res.status( 200 ).json( users )
    })
    .catch(( error ) => {
        return res.status( 403 ).json( error )
    })
})
...
module.exports = router

我的 auth.PassportLocal.js 检查 req.isAuthenticated() 的值

const authPassportLocal = ( req, res, next ) => {
    console.log( req.headers ) // I do not see session has been passed on my request
    console.log( req.body )    // empty
    console.log('isAuthenticated', req.isAuthenticated() ) // log if isAuthenticated returns true. 
    if ( req.isAuthenticated() ) {
         return next()
    }
    return res.redirect('/dashboard/login/index')
}
....
module.exports = authPassportLocal

现在,当我调用 /dashboard/users via fetch API

fetch( '/dashboard/users', {
    headers :{
        'Content-Type' : 'application/x-www-form-urlencoded'
    },
    credentials: 'include',
})
.then(( response ) => response.json())
.then(( users ) => console.log( users ))
.catch(( error ) => console.log( error ))

这返回 isAuthenticated false,我尝试查看从 /dashboard/users 收到的标头,但是,我没有看到任何 cookie 在我的请求中传递。

这是我的 index.js

const express           = require('express')
const session           = require('express-session')
const flash             = require('express-flash')
const cors              = require('cors')
const passport          = require('passport')
const LocalStrategy     = require('passport-local').Strategy
const Users             = require('./routes/Users.routes.js')
const Login             = require('./routes/Login.routes')
const SimpleCmsUsers    = require('./models/Users.models.js')
const app               = express()

app.use( express.json() )
app.use( express.urlencoded({ extended: true }) )
app.use( cors({
     origin: ['http://localhost:3001', 'http://localhost:3000'],
     credentials: true
}))
app.use( flash() )
app.use( session({
    secret: 'EUE7J3lUE01xhmCGQt04S8PbsMpUE5JDcQj0fyS0cy73PQVDLM',       
    resave: true,
    saveUninitialized: true
}))
app.use( passport.initialize() )
app.use( passport.session() )

passport.use( new LocalStrategy(
    {
        // passport-local option here ...
    },
    ( username, password, done ) => {
        try {
            SimpleCmsUsers.find({ user_username : username, user_password : password }, function ( err, docs ) {
                if ( !docs.length ) {
                    return done( null, false, { message: "User not found!" } )
                }
                return done( null, username )
            })
        }
        catch( error ) {
            return done( null, false, { message: error } )
        }
    }
))
passport.serializeUser(function( user, done ) {
    done( null, user );
})
passport.deserializeUser(function( user, done ) {
    done( null, user );
})

app.use('/dashboard/users', Users)
app.use('/dashboard/login', Login)

app.listen( PORT, () => console.log("Express JS is on port " + PORT) )

最让我困扰的是,这些当前的设置可以在没有此类挑战的情况下在 Postman 上运行。

在我的 fetch API 请求中 (http://localhost:3001/dashboard/users'):

url /
headers {
  host: 'localhost:3001',
  connection: 'keep-alive',
  pragma: 'no-cache',
  'cache-control': 'no-cache',
  'sec-fetch-dest': 'empty',
  'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36',
  dnt: '1',
  'content-type': 'application/x-www-form-urlencoded',
  accept: '*/*',
  origin: 'http://localhost:3000',
  'sec-fetch-site': 'same-site',
  'sec-fetch-mode': 'cors',
  referer: 'http://localhost:3000/dashboard/users',
  'accept-encoding': 'gzip, deflate, br',
  'accept-language': 'en-US,en;q=0.9,fil;q=0.8',
  cookie: 'connect.sid=s%3AJEG3MNSqtl33KqmHR2DhGlslnlkMKIPT.xsI%2F%2B82%2F1x8zTlq%2BkRN6aJVVbrauH8qv8jDhsrvNlbY'
}
body {}
user undefined
session Session {
  cookie: { path: '/', _expires: null, originalMaxAge: null, httpOnly: true }
}
isAuthenticated false

在邮递员 (http://localhost:3001/dashboard/users'):

url /
headers {
  'content-type': 'application/x-www-form-urlencoded',
  'user-agent': 'PostmanRuntime/7.22.0',
  accept: '*/*',
  'cache-control': 'no-cache',
  'postman-token': '443a064e-7909-43db-9783-79a6ba8bd4c5',
  host: 'localhost:3001',
  'accept-encoding': 'gzip, deflate, br',
  cookie: 'connect.sid=s%3AsvbYi_oxm4yqXTTa7S-N-3qAT6BdW5-u.QYFAXzayArpV1%2BDbjnwJ3fMMjpLzkM%2Fr9kIUCUCYscY',
  connection: 'keep-alive'
}
body {}
user username
session Session {
  cookie: { path: '/', _expires: null, originalMaxAge: null, httpOnly: true },
  passport: { user: 'username' }
}
isAuthenticated true

只是我看不出哪里出了问题,为什么 fetch API 不能从 connect.sid 传递 cookie 值

非常感谢任何帮助或指导更好地隔离此行为的地方。

TA

更新

npm run start // for react dev server running in port 3000
nodemon api/v1/index.js // for express api running in port 3001

在下面尝试了这些线程,但是,我没有看到任何进展:

passport's req.isAuthenticated always returning false, even when I hardcode done(null, true)

Basics of Passport Session (expressjs)-why do we need to serialize and deserialize?

【问题讨论】:

  • 您必须将快速会话域参数设置为使用端口:3000(前端端口)查看我的答案

标签: javascript reactjs express passport.js passport-local


【解决方案1】:

你的代码是正确的。

唯一的问题是如何设置 cookie。

由于您的后端运行在 :3001 cookie 被设置为主机:localhost:3001

阅读本期:https://github.com/jaredhanson/passport/issues/403

解决方案是让会话中间件通过不同的主机设置cookie

app.use( session({
    secret: 'EUE7J3lUE01xhmCGQt04S8PbsMpUE5JDcQj0fyS0cy73PQVDLM',       
    resave: true,
    saveUninitialized: true,
    cookie: {domain: 'localhost:3000'}
}))

【讨论】:

    猜你喜欢
    • 2014-03-24
    • 2021-04-03
    • 2018-08-06
    • 2021-03-09
    • 2022-07-30
    • 1970-01-01
    • 2016-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多