📜  ExpressJS-身份验证(1)

📅  最后修改于: 2023-12-03 15:00:40.746000             🧑  作者: Mango

ExpressJS 身份验证

在 Web 应用程序中,身份验证是至关重要的。ExpressJS 提供了各种身份验证方法和中间件,可以轻松添加身份验证功能。本文将介绍 ExpressJS 中的身份验证及其实现。

基础身份验证

基础身份验证是最简单的身份验证方法之一。要使用基础身份验证,需要在请求头中添加一个 Authorization 字段,该字段包含用户名和密码的 Base64 编码。在 ExpressJS 中,可以使用 basic-auth 中间件来处理基础身份验证。

const auth = require('basic-auth');
const express = require('express');

const app = express();

app.use((req, res, next) => {
  const user = auth(req);

  if (!user || user.name !== 'username' || user.pass !== 'password') {
    res.set('WWW-Authenticate', 'Basic realm="example"');
    res.status(401).send('Unauthorized');
    return;
  }

  next();
});

app.get('/', (req, res) => {
  res.send('Hello World!');
});

app.listen(3000, () => {
  console.log('Server started on port 3000');
});

以上代码中,basic-auth 中间件会解析请求头中的 Authorization 字段,并将用户名和密码解析为 JavaScript 对象。如果用户名和密码匹配,next 函数将被调用,否则客户端将收到 401 响应。当客户端收到 401 响应时,会弹出一个登录框,要求用户输入用户名和密码。

JSON Web Tokens(JWT)

JSON Web Tokens 是一种用于身份验证的安全方法。JWT 由三部分组成:头部、载荷和签名。头部包含加密算法和类型信息,载荷包含有效负载,例如用户名、角色等,签名用于验证令牌的真实性。在 ExpressJS 中,可以使用 jsonwebtoken 模块来实现 JWT 身份验证。

const jwt = require('jsonwebtoken');
const express = require('express');

const app = express();

const users = [
  { id: 1, username: 'user1', password: 'password1' },
  { id: 2, username: 'user2', password: 'password2' },
  { id: 3, username: 'user3', password: 'password3' }
];

const secret = 'mysecret';

app.use(express.json());

app.post('/login', (req, res) => {
  const { username, password } = req.body;
  const user = users.find(u => u.username === username && u.password === password);

  if (user) {
    const token = jwt.sign({ sub: user.id }, secret);
    res.json({ token });
  } else {
    res.status(401).send('Invalid username or password');
  }
});

app.get('/', (req, res) => {
  const token = req.headers.authorization?.split(' ')[1];

  try {
    const { sub } = jwt.verify(token, secret);
    const user = users.find(u => u.id === sub);
    res.send(`Hello ${user.username}!`);
  } catch (error) {
    res.status(401).send('Unauthorized');
  }
});

app.listen(3000, () => {
  console.log('Server started on port 3000');
});

以上代码中,jsonwebtoken 模块用于创建和验证 JWT。在登录 API 中,如果用户名和密码匹配,将创建 JWT 并将其发送回客户端。在受保护的路由中,解析 Authorization 头中的令牌并验证其真实性。如果验证通过,将从载荷中提取用户 ID,并将其与用户数组中的用户进行匹配。如果找到用户,则向客户端发送欢迎消息,否则向客户端发送 401 响应。

Passport

Passport 是 ExpressJS 中最流行的身份验证中间件之一。Passport 提供了一种简单的方式来处理多种身份验证策略,例如本地身份验证、基础身份验证、JWT 等。使用 Passport,可以轻松实现添加、删除、重用身份验证策略。以下是使用 Passport 的示例:

const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const express = require('express');

const app = express();

const users = [
  { id: 1, username: 'user1', password: 'password1' },
  { id: 2, username: 'user2', password: 'password2' },
  { id: 3, username: 'user3', password: 'password3' }
];

passport.serializeUser((user, done) => {
  done(null, user.id);
});

passport.deserializeUser((id, done) => {
  done(null, users.find(u => u.id === id));
});

passport.use(new LocalStrategy((username, password, done) => {
  const user = users.find(u => u.username === username);

  if (!user || user.password !== password) {
    return done(null, false);
  }

  return done(null, user);
}));

app.use(express.urlencoded({ extended: false }));
app.use(passport.initialize());

app.get('/', (req, res) => {
  res.send('Hello World!');
});

app.post('/login', passport.authenticate('local', {
  successRedirect: '/',
  failureRedirect: '/login',
  failureFlash: true
}));

app.listen(3000, () => {
  console.log('Server started on port 3000');
});

以上代码中,我们创建了一个本地策略并将其传递给 Passport。在本地策略中,我们查找用户并验证其密码。如果用户名和密码匹配,则调用 done(null, user) 方法;如果不匹配,则调用 done(null, false) 方法。

在应用程序中,我们使用 passport.authenticate 中间件来处理身份验证。我们将本地策略的名称传递给中间件,并指定成功重定向 URL、失败重定向 URL 和失败闪存选项。成功重定向 URL 和失败重定向 URL 分别指定成功和失败时要重定向到哪个 URL。失败闪存选项用于将错误消息存储在 session 中,并在下一个请求中使用这些消息。如果身份验证失败,则 Passport 将重定向到 /login 并显示错误消息。

结论

在 ExpressJS 中,有多种身份验证方法和中间件可供使用。无论您选择哪种方法,都应该选择一种适合您的应用程序的方法。希望本文对您有所帮助。