Express + PassportJS 无法读取闪信
Express + PassportJS can't read flash messages
我有我的 Express + Passport + Firebase 项目,我在其中使用本地策略处理身份验证。因为我发现 Passport 会处理身份验证过程,所以我还发现它会接受 flash 消息作为 done()
函数(在策略中)的第三个参数。但我不确定如何阅读它们:
我猜我设置和读取即显消息的流程是:
使用 NPM 安装 connect-flash。
导入后设置Express中间件:
import * as flash from 'connect-flash';
...
const app = express();
...
app.use(flash());
- 根据 documentation:
在 Express 路由中配置 Passport 身份验证
// POST - /api/v1/admin/oauth/login
router.post(
'/login',
async (req: Request, res: Response) => { /* middleware function to validate input */ },
passport.authenticate('local', {
failureRedirect: '/api/v1/admin/oauth/login',
failureFlash: true
}),
async (req: Request, res: Response) => { /* function after success login */
);
- 根据 Passport configuration documentation:
在 done()
方法中包含 flash 消息
import { Strategy as LocalStrategy } from 'passport-local';
import db from '../../config/database';
import * as bcrypt from 'bcryptjs';
export default new LocalStrategy({ usernameField: 'email' }, async (email, password, done) => {
const ref = db.collection('users').doc(email);
try {
const doc = await ref.get();
if (!doc.exists) {
return done(null, false, { error: 'Wrong email' });
}
const user = doc.data();
const match: boolean = await bcrypt.compare(password, user.password);
if (!match) {
return done(null, false, { error: 'Wrong password' });
}
user.id = doc.id;
delete user.password;
return done(null, user);
} catch(error) {
return done(error);
}
});
- 使用
req.flash('error')
读取即显消息:
// GET - /api/v1/admin/oauth/login
router.get('/login', (req: any, res: Response) => {
const result: IResult = {
message: '',
data: null,
ok: false
};
if (req.flash('error')) {
resultado.message = req.flash('error');
console.log(req.flash('error'));
}
return res.status(400).json(result);
});
我认为它在我的脑海中发挥了巨大的作用,直到第 5 步,其中 req.flash('error')
中有一个空数组。我做错了什么?
您传递的即显信息有误!
done()
的第三个参数应该是具有字段 type
和 message
:
的对象
return done(null, false, { message: 'Wrong email' });
类型默认为error
。
这个 API 似乎没有明确记录,但显示在 [=29= 的 配置 章节的 3rd example of the Verify Callback section 中] 文档。
我创建了 a repo,其中包含一个可重现性最低的工作示例。
我一直在搜索并找到了解决方案,但它在第二次登录尝试中有效。
我修改问题的步骤以使其有效:
使用 NPM 安装 connect-flash。
导入后设置Express中间件:
import * as flash from 'connect-flash';
...
const app = express();
...
app.use(flash());
- 根据 documentation:
在 Express 路由中配置 Passport 身份验证
// POST - /api/v1/admin/oauth/login
router.post(
'/login',
async (req: Request, res: Response) => { /* middleware function to validate input */ },
passport.authenticate('local', {
failureFlash: true,
failureRedirect: '/api/v1/admin/oauth/login'
}),
async (req: Request, res: Response) => { /* function after success login */
);
- 创建另一个路由,以便它可以显示 flash 消息,感谢@Codebling:
// GET - /api/v1/admin/oauth/login
router.get('/login', (req: Request, res: Response) => {
const result: IResult = {
message: 'Auth ok',
data: null,
ok: true
};
let status: number = 200;
const flashMessage: any = req.flash('error');
if (flashMessage.length) {
resultado.message = flashMessage[0];
resultado.ok = false;
status = 400;
}
return res.status(status).json(result);
});
- 根据 Passport configuration documentation:
在 done()
方法中包含 flash 消息
import { Strategy as LocalStrategy } from 'passport-local';
import db from '../../config/database';
import * as bcrypt from 'bcryptjs';
export default new LocalStrategy({ usernameField: 'email' }, async (email, password, done) => {
const ref = db.collection('users').doc(email);
try {
const doc = await ref.get();
if (!doc.exists) {
return done(null, false, { message: 'Wrong email' });
}
const user = doc.data();
const match: boolean = await bcrypt.compare(password, user.password);
if (!match) {
return done(null, false, { message: 'Wrong password' });
}
user.id = doc.id;
delete user.password;
return done(null, user);
} catch(error) {
return done(error);
}
});
我有我的 Express + Passport + Firebase 项目,我在其中使用本地策略处理身份验证。因为我发现 Passport 会处理身份验证过程,所以我还发现它会接受 flash 消息作为 done()
函数(在策略中)的第三个参数。但我不确定如何阅读它们:
我猜我设置和读取即显消息的流程是:
使用 NPM 安装 connect-flash。
导入后设置Express中间件:
import * as flash from 'connect-flash';
...
const app = express();
...
app.use(flash());
- 根据 documentation: 在 Express 路由中配置 Passport 身份验证
// POST - /api/v1/admin/oauth/login
router.post(
'/login',
async (req: Request, res: Response) => { /* middleware function to validate input */ },
passport.authenticate('local', {
failureRedirect: '/api/v1/admin/oauth/login',
failureFlash: true
}),
async (req: Request, res: Response) => { /* function after success login */
);
- 根据 Passport configuration documentation: 在
done()
方法中包含 flash 消息
import { Strategy as LocalStrategy } from 'passport-local';
import db from '../../config/database';
import * as bcrypt from 'bcryptjs';
export default new LocalStrategy({ usernameField: 'email' }, async (email, password, done) => {
const ref = db.collection('users').doc(email);
try {
const doc = await ref.get();
if (!doc.exists) {
return done(null, false, { error: 'Wrong email' });
}
const user = doc.data();
const match: boolean = await bcrypt.compare(password, user.password);
if (!match) {
return done(null, false, { error: 'Wrong password' });
}
user.id = doc.id;
delete user.password;
return done(null, user);
} catch(error) {
return done(error);
}
});
- 使用
req.flash('error')
读取即显消息:
// GET - /api/v1/admin/oauth/login
router.get('/login', (req: any, res: Response) => {
const result: IResult = {
message: '',
data: null,
ok: false
};
if (req.flash('error')) {
resultado.message = req.flash('error');
console.log(req.flash('error'));
}
return res.status(400).json(result);
});
我认为它在我的脑海中发挥了巨大的作用,直到第 5 步,其中 req.flash('error')
中有一个空数组。我做错了什么?
您传递的即显信息有误!
done()
的第三个参数应该是具有字段 type
和 message
:
return done(null, false, { message: 'Wrong email' });
类型默认为error
。
这个 API 似乎没有明确记录,但显示在 [=29= 的 配置 章节的 3rd example of the Verify Callback section 中] 文档。
我创建了 a repo,其中包含一个可重现性最低的工作示例。
我一直在搜索并找到了解决方案,但它在第二次登录尝试中有效。
我修改问题的步骤以使其有效:
使用 NPM 安装 connect-flash。
导入后设置Express中间件:
import * as flash from 'connect-flash';
...
const app = express();
...
app.use(flash());
- 根据 documentation: 在 Express 路由中配置 Passport 身份验证
// POST - /api/v1/admin/oauth/login
router.post(
'/login',
async (req: Request, res: Response) => { /* middleware function to validate input */ },
passport.authenticate('local', {
failureFlash: true,
failureRedirect: '/api/v1/admin/oauth/login'
}),
async (req: Request, res: Response) => { /* function after success login */
);
- 创建另一个路由,以便它可以显示 flash 消息,感谢@Codebling:
// GET - /api/v1/admin/oauth/login
router.get('/login', (req: Request, res: Response) => {
const result: IResult = {
message: 'Auth ok',
data: null,
ok: true
};
let status: number = 200;
const flashMessage: any = req.flash('error');
if (flashMessage.length) {
resultado.message = flashMessage[0];
resultado.ok = false;
status = 400;
}
return res.status(status).json(result);
});
- 根据 Passport configuration documentation: 在
done()
方法中包含 flash 消息
import { Strategy as LocalStrategy } from 'passport-local';
import db from '../../config/database';
import * as bcrypt from 'bcryptjs';
export default new LocalStrategy({ usernameField: 'email' }, async (email, password, done) => {
const ref = db.collection('users').doc(email);
try {
const doc = await ref.get();
if (!doc.exists) {
return done(null, false, { message: 'Wrong email' });
}
const user = doc.data();
const match: boolean = await bcrypt.compare(password, user.password);
if (!match) {
return done(null, false, { message: 'Wrong password' });
}
user.id = doc.id;
delete user.password;
return done(null, user);
} catch(error) {
return done(error);
}
});