面试题答案
一键面试- 安装依赖:
- 安装
express
框架,用于构建 Web 应用。 - 安装
express - session
用于管理用户会话,passport
及其策略(如passport - local
用于本地用户名密码认证)等相关中间件。
npm install express express - session passport passport - local
- 安装
- 初始化 Express 应用:
const express = require('express'); const app = express();
- 配置中间件:
- Body 解析中间件:使用
express.json()
和express.urlencoded({ extended: true })
来解析请求体中的 JSON 和 URL 编码数据。
app.use(express.json()); app.use(express.urlencoded({ extended: true }));
- 会话中间件:配置
express - session
,设置密钥、存储方式等。
const session = require('express - session'); app.use(session({ secret: 'your - secret - key', resave: false, saveUninitialized: true }));
- Passport 中间件:初始化
passport
并将其挂载到 Express 应用上。
const passport = require('passport'); app.use(passport.initialize()); app.use(passport.session());
- Body 解析中间件:使用
- 配置 Passport 策略:
- 以
passport - local
为例,配置用户名和密码验证逻辑。
const LocalStrategy = require('passport - local').Strategy; const User = require('./models/user'); // 假设用户模型路径 passport.use(new LocalStrategy( { usernameField: 'email', // 可以自定义用户名字段,这里假设使用邮箱 passwordField: 'password' }, async (email, password, done) => { try { const user = await User.findOne({ email }); if (!user) { return done(null, false, { message: 'User not found' }); } const isMatch = await user.comparePassword(password); // 假设用户模型有比较密码的方法 if (isMatch) { return done(null, user); } else { return done(null, false, { message: 'Invalid password' }); } } catch (error) { return done(error); } } ));
- 以
- 序列化和反序列化用户:
- 序列化:将用户对象存储到会话中。
passport.serializeUser((user, done) => { done(null, user.id); });
- 反序列化:从会话中读取用户对象。
passport.deserializeUser(async (id, done) => { try { const user = await User.findById(id); done(null, user); } catch (error) { done(error); } });
- 创建认证路由:
- 登录路由:使用
passport.authenticate
中间件处理登录逻辑。
app.post('/login', passport.authenticate('local', { successRedirect: '/dashboard', failureRedirect: '/login', failureFlash: true }));
- 注册路由:处理用户注册逻辑,通常包括验证用户输入、创建新用户记录等。
app.post('/register', async (req, res) => { const { email, password } = req.body; try { const newUser = new User({ email, password }); await newUser.save(); res.redirect('/login'); } catch (error) { res.status(400).send(error.message); } });
- 登录路由:使用
- 保护路由:
- 使用
isAuthenticated
中间件(可自定义实现)来保护需要认证才能访问的路由。
const isAuthenticated = (req, res, next) => { if (req.isAuthenticated()) { return next(); } res.redirect('/login'); }; app.get('/dashboard', isAuthenticated, (req, res) => { res.send('Welcome to the dashboard'); });
- 使用
- 处理注销:
- 提供注销路由,清除用户会话。
app.get('/logout', (req, res) => { req.logout((err) => { if (err) { return next(err); } res.redirect('/login'); }); });
常用的中间件:
express - session
:管理用户会话,存储用户状态。passport
:灵活的认证中间件,支持多种认证策略。passport - local
:基于用户名和密码的本地认证策略。
技术点:
- 会话管理:理解如何通过会话跟踪用户状态。
- 密码哈希:在存储用户密码时使用合适的哈希算法,如
bcrypt
,确保密码安全。 - 策略配置:根据不同的认证需求配置合适的
passport
策略。 - 用户模型设计:设计合理的用户数据模型,包含必要的字段和方法。