我有我的Express + Passport + Firebase项目,我在其中使用本地策略处理身份验证。由于我发现Passport将负责身份验证过程,因此我也发现它会接受Flash消息作为done()
函数的第三个参数(在策略中)。但我不确定如何阅读它们:
我想我设置和读取Flash消息的流程是:
使用NPM安装connect-flash。
导入后设置Express中间件:
import * as flash from 'connect-flash';
...
const app = express();
...
app.use(flash());
// 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 */
);
done()
,将Flash消息包括在Passport configuration documentation方法中。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')
中都有一个空数组。我做错了吗?
您传递的Flash消息错误!
done()
的第三个参数应该是具有字段type
和message
的对象:
return done(null, false, { message: 'Wrong email' });
类型默认为error
。
此API似乎没有明确记录,但在Passport.js文档的Configure章节的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());
// 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 */
);
// 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);
});
done()
,将Flash消息包括在Passport configuration documentation方法中。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);
}
});