我希望有人能阐明我的情况。 req.isAuthenticated()在通过获取API在app.router端点(在端口3001 中运行)调用后,始终返回false。看来,当我执行 req.isAuthenticated()
时,connect.sid未成功传递给req arg另一方面,我的React开发服务器运行在端口3000
这是我当前的设置。
登录路径,该路径用于验证用户名和密码,并通过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
现在,当我通过获取API调用 / dashboard / users 时
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上运行。
在我的提取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
我只是看不到出了什么问题,为什么提取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?
答案 0 :(得分:0)
您的验证码是正确的。
唯一的问题是如何设置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'}
}))