MST

星途 面试题库

面试题:Node.js 中 Express 实现用户认证的基本流程

在 Node.js 的 Express 框架下,简述实现用户认证系统的基本步骤,包括常用的中间件和技术点。
43.0万 热度难度
前端开发Node.js

知识考点

AI 面试

面试题答案

一键面试
  1. 安装依赖
    • 安装express框架,用于构建 Web 应用。
    • 安装express - session用于管理用户会话,passport及其策略(如passport - local用于本地用户名密码认证)等相关中间件。
    npm install express express - session passport passport - local
    
  2. 初始化 Express 应用
    const express = require('express');
    const app = express();
    
  3. 配置中间件
    • 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());
    
  4. 配置 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);
            }
        }
    ));
    
  5. 序列化和反序列化用户
    • 序列化:将用户对象存储到会话中。
    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);
        }
    });
    
  6. 创建认证路由
    • 登录路由:使用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);
        }
    });
    
  7. 保护路由
    • 使用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');
    });
    
  8. 处理注销
    • 提供注销路由,清除用户会话。
    app.get('/logout', (req, res) => {
        req.logout((err) => {
            if (err) {
                return next(err);
            }
            res.redirect('/login');
        });
    });
    

常用的中间件:

  • express - session:管理用户会话,存储用户状态。
  • passport:灵活的认证中间件,支持多种认证策略。
  • passport - local:基于用户名和密码的本地认证策略。

技术点:

  • 会话管理:理解如何通过会话跟踪用户状态。
  • 密码哈希:在存储用户密码时使用合适的哈希算法,如bcrypt,确保密码安全。
  • 策略配置:根据不同的认证需求配置合适的passport策略。
  • 用户模型设计:设计合理的用户数据模型,包含必要的字段和方法。