javascript - Passport JS - 帮助,没有调用反序列化用户
问题描述
我有一个调用 Express API 的 React 应用程序,它使用 Passport JS 通过本地策略进行身份验证。
客户端登录页面调用/auth/login
路由成功。req.user
被发送回客户端,并调用序列化函数(我有一个打印的 console.log)。
Router.post('/login', passport.authenticate('local'), (req, res) => {
res.send(req.user);
})
后续请求从中获取用户信息/auth/instructor
不起作用。req.user
返回 undefined 并且deserializeUser()
永远不会被调用。
Router.get('/instructor', (req,res)=>{
console.log(req.user)
if(req.user) res.send(req.user)
else res.send({username: "No user logged in"})
})
我相信我的护照和会话配置设置正确。
const passportLocal = require('passport-local').Strategy
const bcrypt = require('bcryptjs')
const instructor = require('../Models/instructor.model')
module.exports = function(passport){
const strategy = new passportLocal( (username, password, done)=> {
console.log(username, password)
instructor
.findOne({username})
.then( instructor => {
if (!instructor) return done(null, false)
if (bcrypt.compareSync(password, instructor.password)) return done( null, instructor)
return (null, false)
})
.catch( error => console.log(error))
})
passport.use(strategy)
passport.serializeUser( (user, done)=> {
console.log('serialize', user._id)
done(null, user._id)
})
passport.deserializeUser( (id, done)=> {
console.log('de-serialize', id)
instructor.findById(id).then( instuctor => done( null, instructor))
})
}
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const cors = require('cors')
const session = require('express-session')
const passport = require('passport')
// Import routers
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
const pupilsRouter = require('./routes/pupils.routes');
const authRouter = require('./routes/auth.routes');
// Connect to database
require('./config/mongoose.config.js');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser("secret"));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(session({
secret: "secret",
resave: true,
saveUninitialized: true,
cookie: {secure: false}
}))
app.use(cors({
origin: "http://localhost:3003",
credentials: true,
}))
// Initialize Passport Middleware
app.use(passport.initialize())
app.use(passport.session())
require('./config/passport.config')(passport)
// Use Routers
app.use('/api', indexRouter);
app.use('/api/users', usersRouter);
app.use('/api/pupils', pupilsRouter);
app.use('/api/auth', authRouter);
app.get('/api/ping', (req, res) => res.send("server is working"))
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
const Router = require('express').Router()
const Instructor = require('../Models/instructor.model');
const bcrypt = require('bcryptjs');
const passport = require('passport');
Router.post('/register', (req, res) => {
Instructor.findOne({username: req.body.username}).then( results => {
if (!results) {
const instructorData = {...(req.body), password: bcrypt.hashSync(req.body.password) }
Instructor.create(instructorData).then(console.log)
res.send("Instructor registered")
} else {
res.status(400).send("Instructor Already Exists")
}
} )
})
Router.post('/login', passport.authenticate('local'), (req, res) => {
res.send(req.user);
})
Router.get('/instructor', (req,res)=>{
console.log(req.user)
if(req.user) res.send(req.user)
else res.send({username: "No user logged in"})
})
module.exports = Router
这是我要开始工作的客户端代码。单击配置文件按钮应该从会话中获取用户并显示用户名。
import React, { useState, useEffect } from 'react'
import { NavLink} from 'react-router-dom'
import styled from 'styled-components';
import axios from 'axios'
import Logo from './Logo'
axios.defaults.withCredentials = true;
function Header() {
const [user, setUser] = useState({})
useEffect( ()=>{
axios
.get( 'http://localhost:3000/api/auth/instructor')
.then( response => setUser( response.data ))
} ,[])
const getUser = ()=> {
axios
.get( 'http://localhost:3000/api/auth/instructor')
.then( response => setUser( response.data ))
}
return (
<StyledDiv>
<Logo/>
<div className="auth">
<NavLink to="/auth/login"> Login </NavLink>
<NavLink to="/auth/register"> Register </NavLink>
<button className="profile-button" onClick={getUser}>{user.username || "Get User"}</button>
</div>
</StyledDiv>
)
}
const StyledDiv = styled.div`
width: 100vw; height: 90px;
display: grid; place-content: center;
position: relative;
box-shadow: 0px 3px 5px 5px lightgray, 0px 2px 1px 1px black;
div.auth {
position: absolute;
right: 50px; top: 35px;
a {
margin-right: 7px;
}
}
.user-profile {
background: purple;
color: white;
}
`
export default Header
检查网络请求,客户端似乎正在设置 SID cookie 并毫无问题地发出 cors 请求。但是 req.user 没有数据..
感谢这里的任何帮助,我要疯了。
解决方案
您的回调函数中似乎有一个错字 ( instuctor
)。
使固定:
passport.deserializeUser( (id, done)=> {
console.log('de-serialize', id);
instructor.findById(id).then((instructor) => done( null, instructor));
})
如果您使用的是 VS Code,我还推荐一个拼写检查插件。
推荐阅读
- html - 我的 index.html 中的任何更改都不会反映在网页上。为什么?
- c# - 从起点、终点和距离计算坐标
- javascript - Facebook 嵌入了“JOIN GROUP”按钮事件 .. 类似 Onclick
- amazon-ec2 - 使用 SNS 触发 EC2 自动缩放
- image - 如何在 React Native 中检测图像是否为全景图?
- intellij-idea - Intellij:在创建新文件时将“JUnit”添加到上下文菜单
- pascal - 如何擦除以前在控制台上写入的字符?
- python-3.x - 计算逻辑回归分类器的精度、召回率和 F 度量
- azure - 为什么 BasicLuisDialog.cs 不在网络应用程序机器人的对话框部分?
- php - 如何使用户的个人资料页面可编辑,我想在编辑后保存这些数据(vue.js + laravel)