You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于登录用户自定义Node.js Express API端点URL?

实现基于登录用户的Express API路由控制

要实现localhost:8080/api/v1/user/${username}这种自定义端点,并确保用户仅能访问自身账户数据,核心思路是先认证获取当前用户信息,再校验URL参数与当前用户的一致性。以下是具体实现步骤和代码示例:

核心步骤

  1. 用户认证:通过JWT验证用户身份,将登录用户信息挂载到请求对象上。
  2. 权限校验中间件:对比URL参数中的username和当前登录用户的username,不一致则拒绝访问。
  3. 重构路由:将查询、更新、删除等接口改为/:username结构,并挂载认证和权限校验中间件。

代码实现

1. 安装依赖

先安装所需包:

npm install express jsonwebtoken dotenv

2. 认证与权限校验中间件

创建middleware/auth.js:

const jwt = require('jsonwebtoken');

// 解析请求头中的JWT令牌,获取当前用户信息
const authenticateUser = (req, res, next) => {
  const authHeader = req.headers.authorization;
  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    return res.status(401).json({ message: '未提供有效认证令牌' });
  }

  const token = authHeader.split(' ')[1];
  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded; // 将用户信息挂载到req对象
    next();
  } catch (err) {
    return res.status(401).json({ message: '认证令牌无效或已过期' });
  }
};

// 权限校验:确保用户只能访问自己的资源
const authorizeOwnResource = (req, res, next) => {
  const { username } = req.params;
  if (req.user.username !== username) {
    return res.status(403).json({ message: '无权访问该资源' });
  }
  next();
};

module.exports = { authenticateUser, authorizeOwnResource };

3. 用户路由配置

创建routes/user.js:

const express = require('express');
const jwt = require('jsonwebtoken');
const { authenticateUser, authorizeOwnResource } = require('../middleware/auth');
const router = express.Router();

// 注册接口(无需认证)
router.post('/auth/register', (req, res) => {
  const { username, password, email } = req.body;
  // 此处省略数据库创建用户的逻辑(如加密密码、存储用户信息)
  
  const token = jwt.sign({ username }, process.env.JWT_SECRET, { expiresIn: '1d' });
  res.status(201).json({ message: '注册成功', token });
});

// 登录接口(无需认证)
router.post('/auth/login', (req, res) => {
  const { username, password } = req.body;
  // 此处省略数据库验证用户名密码的逻辑
  
  const token = jwt.sign({ username }, process.env.JWT_SECRET, { expiresIn: '1d' });
  res.json({ message: '登录成功', token });
});

// 获取当前用户信息(需要认证+权限校验)
router.get('/:username', authenticateUser, authorizeOwnResource, (req, res) => {
  // 此处省略从数据库查询用户信息的逻辑,用req.user.username作为查询条件
  res.json({
    username: req.user.username,
    email: 'user@example.com',
    createdAt: '2024-01-01'
  });
});

// 更新当前用户信息(需要认证+权限校验)
router.put('/:username', authenticateUser, authorizeOwnResource, (req, res) => {
  const { email, password } = req.body;
  // 此处省略数据库更新用户信息的逻辑,用req.user.username作为查询条件
  
  res.json({
    message: '用户信息更新成功',
    user: { username: req.user.username, email }
  });
});

// 删除当前用户账户(需要认证+权限校验)
router.delete('/:username', authenticateUser, authorizeOwnResource, (req, res) => {
  // 此处省略数据库删除用户的逻辑,用req.user.username作为查询条件
  res.json({ message: '账户已成功删除' });
});

module.exports = router;

4. 主应用入口

创建app.js:

const express = require('express');
const userRouter = require('./routes/user');
require('dotenv').config();

const app = express();
app.use(express.json()); // 解析JSON请求体

// 挂载用户路由
app.use('/api/v1/user', userRouter);

const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
  console.log(`服务器运行在 http://localhost:${PORT}`);
});

5. 环境变量配置

创建.env文件:

JWT_SECRET=your_secure_jwt_secret_key_here
PORT=8080

关键说明

  • 注册和登录接口保留原有/auth路径,因为这两个操作不需要用户预先登录。
  • 所有涉及用户自身资源的操作(查询、更新、删除)都必须经过authenticateUser和authorizeOwnResource中间件,确保只有用户本人能访问对应的/:username端点。
  • 即使恶意用户构造其他用户名的URL(如/api/v1/user/anotheruser),权限校验中间件会对比当前登录用户的username,不一致则返回403禁止访问。

内容的提问来源于stack exchange,提问作者Prashant Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 17:08:14