Fastify-passport req.user 为空,反序列化器永远不会被调用,序列化器也不会被调用
Fastify-passport req.user is null, deserializer never gets called nor does the serializer
我一直在努力使用 fastify-passport 库,主要是因为似乎没有人使用它,也没有任何好的例子或与之相关的问题
无论如何,我有一些这样定义的路线:
const adminRoutes = [
{
handler: (req,res) => {console.log(req.user) },
url: "/logout",
method: "GET"
}
]
这条路由然后被fastify这样注册了(注意还有更多的路由,不过这只是一个代码片段)
adminRoutes.forEach((route, index) => {
fastify.route(route)
})
我正在使用护照本地策略进行身份验证,它是这样配置的
fastifyPassport.use('login', new passportLocal(async function (username, password, done) {
try {
let data = await dbQuery(`SELECT * FROM \`users\` WHERE username="${username}"`)
if (data[0].length > 0) {
data = data[0][0]
if (username === data.username && bCrypt.compareSync(password, data.hashedPassword)) {
return done(null, username)
} else return done(null, false)
}
} catch (error) {
console.log(error)
done(error);
}
}))
这似乎有效,在我所有的测试中,该策略完成了它必须做的事情,当通过了正确的用户和密码时,所有检查似乎都通过了并一直到 return done(null, username)
这是我的序列化器和反序列化器
fastifyPassport.registerUserSerializer(async (user, request) => {
return user
});
fastifyPassport.registerUserDeserializer(async (username, request) => {
let data = await dbQuery(`SELECT * FROM users WHERE username="${username}"`);
return data[0][0]
});
我已经检查了调试器和控制台日志,它们似乎从未被调用过
事实上,当我进入 /logout 时,我的控制台抛出一个 null
也没有生成会话 cookie(不确定,有时它似乎生成,其他时候却没有)
完整的代码比较长,不过有必要看看是什么问题
就是这样
这是服务器
require('dotenv').config()
const fastify = require('fastify')({ logger: false })
const fastifyPassport = require('fastify-passport')
const fastifySecureSession = require('fastify-secure-session')
const passportLocal = require('passport-local').Strategy
const BannedEverywhere = ["DROP", "CREATE"]
const bCrypt = require('bcryptjs')
const fs = require('fs')
const path = require('path')
const port = process.env.PORT || 3000
const routes = require('./routes')
const mysql = require('mysql2/promise');
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: process.env.DB_PASSWD,
database: 'users',
port: 3306
});
console.log("Server Connected!")
function dbQuery(dataExpression) {
if (BannedEverywhere.some(i => dataExpression.includes(i))) {
return "invalid"
}
return pool.query(dataExpression)
}
fastify.register(require('fastify-cors'), {
origin: (origin, cb) => {
cb(null, true);
return
}
})
fastify.register(fastifySecureSession, { key: fs.readFileSync(path.join(__dirname, 'secret-key'))})
fastify.register(fastifyPassport.initialize())
fastify.register(fastifyPassport.secureSession())
fastifyPassport.registerUserSerializer(async (user, request) => {
return user
});
fastifyPassport.registerUserDeserializer(async (username, request) => {
let data = await dbQuery(`SELECT * FROM users WHERE username="${username}"`);
return data[0][0]
});
fastifyPassport.use('login', new passportLocal(async function (username, password, done) {
try {
let data = await dbQuery(`SELECT * FROM \`users\` WHERE username="${username}"`)
if (data[0].length > 0) {
data = data[0][0]
if (username === data.username && bCrypt.compareSync(password, data.hashedPassword)) {
console.log("got here")
return done(null, username)
} else return done(null, false)
}
} catch (error) {
console.log(error)
done(error);
}
}))
const postData = async (req, reply, err, user, info, status) => {
if (err !== null) { console.warn("ah habido un error: " + err) }
else if (user) {
const params = req.body
const newData = {
universidad: params.universidad,
facultad: params.facultad,
nombreExamen: params.nombreExamen,
fechaExamen: params.fechaExamen,
convocatoriaEspecial: params.convocatoriaEspecial,
convocatoriaExtraordinaria: params.convocatoriaExtraordinaria,
curso: params.curso
}
const response = await dbQuery('INSERT INTO `examenes` VALUES("'
+ newData.universidad + '","' + newData.facultad + '","'
+ newData.nombreExamen + '","' + newData.fechaExamen + '",'
+ newData.convocatoriaEspecial + ',' + newData.convocatoriaExtraordinaria + ','
+ newData.curso + ")")
return reply.send({ status: 200, newData, response })
}
}
const deleteData = async (req, reply, err, user, info, status) => {
if (err !== null) { console.warn("ah habido un error: " + err) }
else if (user) {
const { universidad, facultad, nombreExamen, fechaExamen, curso } = req.body
const response = await dbQuery('DELETE FROM `examenes` WHERE universidad="' + universidad + '" and facultad="' + facultad + '" and nombreExamen="' + nombreExamen + '" and date(fechaExamen)="' + fechaExamen + '" and curso=' + curso)
return reply.send({ status: 200, response })
}
}
const logout = async (req, reply, err, user, info, status) => {
if (err !== null) { console.warn("ah habido un error: " + err) }
console.log(req)
console.log("--------------------------------")
console.log(user)
console.log("--------------------------------")
console.log(info)
console.log("--------------------------------")
console.log(status)
}
fastify.get(
"/login",
(req, reply) => {
return reply.sendFile('./login/index.html')
}
)
fastify.post(
"/login",
{preValidation: fastifyPassport.authenticate('login',(req, reply)=>{
reply.send({redirect: "/"})
})},
() => {}
)
const adminRoutes = [
{
handler: () => {},
preValidation: fastifyPassport.authenticate("login", deleteData),
url: '/api/deleteData',
method: 'POST'
},
{
handler: () => {},
preValidation: fastifyPassport.authenticate("login", postData),
url: '/api/postData',
method: 'POST'
},
{
handler: () => {},
preValidation: fastifyPassport.authenticate("login", (req, reply) => { return reply.sendFile('./entry/index.html') }),
url: '/entry',
method: 'GET'
},
{
handler: (req,res) => {console.log(req.user) },
url: "/logout",
method: "GET"
}
]
const start = async () => {
try {
await fastify.listen(port)
} catch (err) {
console.error(err)
process.exit(1)
}
}
fastify.register(require('fastify-static'), {
root: __dirname,
prefix: '/', // optional: default '/'
})
routes.forEach((route, index) => {
fastify.route(route)
})
adminRoutes.forEach((route, index) => {
fastify.route(route)
})
start()
在你发表评论之前,我知道 cors 不应该像这样留在生产中,别担心,我知道
另外logout
功能只是一个测试,试图解决这个问题
这是调用 login
post 请求的代码
const HOST = location.origin;
const axiosApp = axios.create({
baseURL: HOST,
});
document
.querySelector("#submit")
.addEventListener("click", async function () {
let response = await axiosApp.post(`${HOST}/login`, {
username: document.querySelector("#username").value,
password: document.querySelector("#password").value,
});
console.log(response);
if(response.status == 200) {
document.location.href = response.data.redirect
}
});
无关,bannedEverywhere 只是一个基本的“安全”检查,我确实计划改进它,现在总比没有好,而且,我确实计划用模板更改所有 var + string + var
链字符串
回答我自己的问题:
当您在 preValidation 中添加回调时
{preValidation: fastifyPassport.authenticate('login',(req, reply)=>{
reply.send({redirect: "/"})
})}
fastify-passport 不再自行处理序列化和反序列化,随之而来的是......更多问题,将预验证更改为
{preValidation: fastifyPassport.authenticate('login'{successRedirect:"/"})
使您必须在浏览器中处理 302 代码,这至少可以说是有问题的
我一直在努力使用 fastify-passport 库,主要是因为似乎没有人使用它,也没有任何好的例子或与之相关的问题
无论如何,我有一些这样定义的路线:
const adminRoutes = [
{
handler: (req,res) => {console.log(req.user) },
url: "/logout",
method: "GET"
}
]
这条路由然后被fastify这样注册了(注意还有更多的路由,不过这只是一个代码片段)
adminRoutes.forEach((route, index) => {
fastify.route(route)
})
我正在使用护照本地策略进行身份验证,它是这样配置的
fastifyPassport.use('login', new passportLocal(async function (username, password, done) {
try {
let data = await dbQuery(`SELECT * FROM \`users\` WHERE username="${username}"`)
if (data[0].length > 0) {
data = data[0][0]
if (username === data.username && bCrypt.compareSync(password, data.hashedPassword)) {
return done(null, username)
} else return done(null, false)
}
} catch (error) {
console.log(error)
done(error);
}
}))
这似乎有效,在我所有的测试中,该策略完成了它必须做的事情,当通过了正确的用户和密码时,所有检查似乎都通过了并一直到 return done(null, username)
这是我的序列化器和反序列化器
fastifyPassport.registerUserSerializer(async (user, request) => {
return user
});
fastifyPassport.registerUserDeserializer(async (username, request) => {
let data = await dbQuery(`SELECT * FROM users WHERE username="${username}"`);
return data[0][0]
});
我已经检查了调试器和控制台日志,它们似乎从未被调用过
事实上,当我进入 /logout 时,我的控制台抛出一个 null
也没有生成会话 cookie(不确定,有时它似乎生成,其他时候却没有)
完整的代码比较长,不过有必要看看是什么问题
就是这样
这是服务器
require('dotenv').config()
const fastify = require('fastify')({ logger: false })
const fastifyPassport = require('fastify-passport')
const fastifySecureSession = require('fastify-secure-session')
const passportLocal = require('passport-local').Strategy
const BannedEverywhere = ["DROP", "CREATE"]
const bCrypt = require('bcryptjs')
const fs = require('fs')
const path = require('path')
const port = process.env.PORT || 3000
const routes = require('./routes')
const mysql = require('mysql2/promise');
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: process.env.DB_PASSWD,
database: 'users',
port: 3306
});
console.log("Server Connected!")
function dbQuery(dataExpression) {
if (BannedEverywhere.some(i => dataExpression.includes(i))) {
return "invalid"
}
return pool.query(dataExpression)
}
fastify.register(require('fastify-cors'), {
origin: (origin, cb) => {
cb(null, true);
return
}
})
fastify.register(fastifySecureSession, { key: fs.readFileSync(path.join(__dirname, 'secret-key'))})
fastify.register(fastifyPassport.initialize())
fastify.register(fastifyPassport.secureSession())
fastifyPassport.registerUserSerializer(async (user, request) => {
return user
});
fastifyPassport.registerUserDeserializer(async (username, request) => {
let data = await dbQuery(`SELECT * FROM users WHERE username="${username}"`);
return data[0][0]
});
fastifyPassport.use('login', new passportLocal(async function (username, password, done) {
try {
let data = await dbQuery(`SELECT * FROM \`users\` WHERE username="${username}"`)
if (data[0].length > 0) {
data = data[0][0]
if (username === data.username && bCrypt.compareSync(password, data.hashedPassword)) {
console.log("got here")
return done(null, username)
} else return done(null, false)
}
} catch (error) {
console.log(error)
done(error);
}
}))
const postData = async (req, reply, err, user, info, status) => {
if (err !== null) { console.warn("ah habido un error: " + err) }
else if (user) {
const params = req.body
const newData = {
universidad: params.universidad,
facultad: params.facultad,
nombreExamen: params.nombreExamen,
fechaExamen: params.fechaExamen,
convocatoriaEspecial: params.convocatoriaEspecial,
convocatoriaExtraordinaria: params.convocatoriaExtraordinaria,
curso: params.curso
}
const response = await dbQuery('INSERT INTO `examenes` VALUES("'
+ newData.universidad + '","' + newData.facultad + '","'
+ newData.nombreExamen + '","' + newData.fechaExamen + '",'
+ newData.convocatoriaEspecial + ',' + newData.convocatoriaExtraordinaria + ','
+ newData.curso + ")")
return reply.send({ status: 200, newData, response })
}
}
const deleteData = async (req, reply, err, user, info, status) => {
if (err !== null) { console.warn("ah habido un error: " + err) }
else if (user) {
const { universidad, facultad, nombreExamen, fechaExamen, curso } = req.body
const response = await dbQuery('DELETE FROM `examenes` WHERE universidad="' + universidad + '" and facultad="' + facultad + '" and nombreExamen="' + nombreExamen + '" and date(fechaExamen)="' + fechaExamen + '" and curso=' + curso)
return reply.send({ status: 200, response })
}
}
const logout = async (req, reply, err, user, info, status) => {
if (err !== null) { console.warn("ah habido un error: " + err) }
console.log(req)
console.log("--------------------------------")
console.log(user)
console.log("--------------------------------")
console.log(info)
console.log("--------------------------------")
console.log(status)
}
fastify.get(
"/login",
(req, reply) => {
return reply.sendFile('./login/index.html')
}
)
fastify.post(
"/login",
{preValidation: fastifyPassport.authenticate('login',(req, reply)=>{
reply.send({redirect: "/"})
})},
() => {}
)
const adminRoutes = [
{
handler: () => {},
preValidation: fastifyPassport.authenticate("login", deleteData),
url: '/api/deleteData',
method: 'POST'
},
{
handler: () => {},
preValidation: fastifyPassport.authenticate("login", postData),
url: '/api/postData',
method: 'POST'
},
{
handler: () => {},
preValidation: fastifyPassport.authenticate("login", (req, reply) => { return reply.sendFile('./entry/index.html') }),
url: '/entry',
method: 'GET'
},
{
handler: (req,res) => {console.log(req.user) },
url: "/logout",
method: "GET"
}
]
const start = async () => {
try {
await fastify.listen(port)
} catch (err) {
console.error(err)
process.exit(1)
}
}
fastify.register(require('fastify-static'), {
root: __dirname,
prefix: '/', // optional: default '/'
})
routes.forEach((route, index) => {
fastify.route(route)
})
adminRoutes.forEach((route, index) => {
fastify.route(route)
})
start()
在你发表评论之前,我知道 cors 不应该像这样留在生产中,别担心,我知道
另外logout
功能只是一个测试,试图解决这个问题
这是调用 login
post 请求的代码
const HOST = location.origin;
const axiosApp = axios.create({
baseURL: HOST,
});
document
.querySelector("#submit")
.addEventListener("click", async function () {
let response = await axiosApp.post(`${HOST}/login`, {
username: document.querySelector("#username").value,
password: document.querySelector("#password").value,
});
console.log(response);
if(response.status == 200) {
document.location.href = response.data.redirect
}
});
无关,bannedEverywhere 只是一个基本的“安全”检查,我确实计划改进它,现在总比没有好,而且,我确实计划用模板更改所有 var + string + var
链字符串
回答我自己的问题:
当您在 preValidation 中添加回调时
{preValidation: fastifyPassport.authenticate('login',(req, reply)=>{
reply.send({redirect: "/"})
})}
fastify-passport 不再自行处理序列化和反序列化,随之而来的是......更多问题,将预验证更改为
{preValidation: fastifyPassport.authenticate('login'{successRedirect:"/"})
使您必须在浏览器中处理 302 代码,这至少可以说是有问题的