首页 > 编程语言 >Node.js JWT认证教程

Node.js JWT认证教程

时间:2024-12-04 11:01:34浏览次数:9  
标签:Node const res require JWT auth js json

Node.js JWT认证教程

1. 项目介绍

JSON Web Token (JWT) 是一种安全的跨域身份验证解决方案,在现代Web应用中广泛使用。本教程将详细讲解如何在Node.js中实现JWT认证。

2. 项目准备

2.1 初始化项目

# 创建项目目录
mkdir nodejs-jwt-auth
cd nodejs-jwt-auth

# 初始化项目
npm init -y

# 安装依赖
npm install express jsonwebtoken bcryptjs body-parser

2.2 项目依赖说明

  • express: Web应用框架
  • jsonwebtoken: JWT生成与验证
  • bcryptjs: 密码加密
  • body-parser: 解析请求体

3. 项目结构

nodejs-jwt-auth/
│
├── config/
│   └── database.js
├── models/
│   └── user.js
├── middleware/
│   └── auth.js
├── routes/
│   └── auth.js
├── server.js
└── package.json

4. 详细实现

4.1 数据库配置 (config/database.js)

module.exports = {
  secret: 'your_jwt_secret_key',
  database: 'mongodb://localhost:27017/jwt-auth-demo'
};

4.2 用户模型 (models/user.js)

const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');

const UserSchema = new mongoose.Schema({
  username: {
    type: String,
    required: true,
    unique: true
  },
  password: {
    type: String,
    required: true
  }
});

// 密码加密中间件
UserSchema.pre('save', function(next) {
  if (!this.isModified('password')) return next();
  
  bcrypt.genSalt(10, (err, salt) => {
    if (err) return next(err);
    
    bcrypt.hash(this.password, salt, (err, hash) => {
      if (err) return next(err);
      this.password = hash;
      next();
    });
  });
});

// 密码验证方法
UserSchema.methods.comparePassword = function(candidatePassword) {
  return bcrypt.compareSync(candidatePassword, this.password);
};

module.exports = mongoose.model('User', UserSchema);

4.3 认证中间件 (middleware/auth.js)

const jwt = require('jsonwebtoken');
const config = require('../config/database');

module.exports = (req, res, next) => {
  const token = req.headers['authorization'];
  
  if (!token) {
    return res.status(403).json({ 
      success: false, 
      message: '未提供认证Token' 
    });
  }

  jwt.verify(token, config.secret, (err, decoded) => {
    if (err) {
      return res.status(401).json({ 
        success: false, 
        message: 'Token无效' 
      });
    }
    
    req.userId = decoded.id;
    next();
  });
};

4.4 路由 (routes/auth.js)

const express = require('express');
const jwt = require('jsonwebtoken');
const router = express.Router();
const User = require('../models/user');
const config = require('../config/database');
const authMiddleware = require('../middleware/auth');

// 用户注册
router.post('/register', async (req, res) => {
  try {
    const { username, password } = req.body;
    
    const existingUser = await User.findOne({ username });
    if (existingUser) {
      return res.status(400).json({ 
        success: false, 
        message: '用户已存在' 
      });
    }

    const user = new User({ username, password });
    await user.save();

    res.status(201).json({ 
      success: true, 
      message: '注册成功' 
    });
  } catch (error) {
    res.status(500).json({ 
      success: false, 
      message: '服务器错误' 
    });
  }
});

// 用户登录
router.post('/login', async (req, res) => {
  try {
    const { username, password } = req.body;
    
    const user = await User.findOne({ username });
    if (!user) {
      return res.status(401).json({ 
        success: false, 
        message: '用户不存在' 
      });
    }

    const isMatch = user.comparePassword(password);
    if (!isMatch) {
      return res.status(401).json({ 
        success: false, 
        message: '密码错误' 
      });
    }

    const token = jwt.sign(
      { id: user._id }, 
      config.secret, 
      { expiresIn: '24h' }
    );

    res.json({ 
      success: true, 
      token: `Bearer ${token}` 
    });
  } catch (error) {
    res.status(500).json({ 
      success: false, 
      message: '服务器错误' 
    });
  }
});

// 受保护的路由
router.get('/profile', authMiddleware, async (req, res) => {
  try {
    const user = await User.findById(req.userId).select('-password');
    res.json({ 
      success: true, 
      user 
    });
  } catch (error) {
    res.status(500).json({ 
      success: false, 
      message: '服务器错误' 
    });
  }
});

module.exports = router;

4.5 服务器入口 (server.js)

const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const config = require('./config/database');
const authRoutes = require('./routes/auth');

const app = express();

// 数据库连接
mongoose.connect(config.database, {
  useNewUrlParser: true,
  useUnifiedTopology: true
});

// 中间件
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// 路由
app.use('/api/auth', authRoutes);

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`服务器运行在 ${PORT} 端口`);
});

5. 使用说明

5.1 注册用户

POST /api/auth/register
{
  "username": "testuser",
  "password": "123456"
}

5.2 用户登录

POST /api/auth/login
{
  "username": "testuser",
  "password": "123456"
}

5.3 访问受保护路由

GET /api/auth/profile
Authorization: Bearer <token>

6. 安全建议

  1. 使用HTTPS保护传输
  2. 定期更新JWT密钥
  3. 设置合理的Token过期时间
  4. 对敏感操作进行二次验证

7. 注意事项

  • 生产环境中应使用环境变量管理密钥
  • 建议使用更强的加密算法
  • 根据实际需求调整Token过期策略

标签:Node,const,res,require,JWT,auth,js,json
From: https://blog.csdn.net/wscfan/article/details/144223401

相关文章

  • curl post json数据
    参考:https://www.cnblogs.com/kelelipeng/p/17129941.htmlcurl-XPOSThttp://127.0.0.1:9991/api/v1/partner/add-H"Content-Type:application/json"-d'{"name":"yl-online-bn","description":"indiapartneronli......
  • 空气质量检测平台js爬虫逆向分析
    空气质量检测平台JS爬虫逆向分析本文将展示如何使用Python构建一个爬虫,抓取空气质量检测平台的数据,并对其进行逆向分析。1.背景介绍我们需要抓取空气质量检测平台提供的实时空气质量数据。在此过程中,我们遇到了一个常见的问题:请求的数据是经过加密的,需要我们对请求和响应的JS......
  • DevExtreme JS & ASP.NET Core v24.2新功能预览 - 全新的聊天组件
    DevExtreme拥有高性能的HTML5/JavaScript小部件集合,使您可以利用现代Web开发堆栈(包括React,Angular,ASP.NETCore,jQuery,Knockout等)构建交互式的Web应用程序。从Angular和Reac,到ASP.NETCore或Vue,DevExtreme包含全面的高性能和响应式UI小部件集合,可在传统Web和下一代移动应用程......
  • DevExtreme JS & ASP.NET Core v24.2新功能预览 - 全新的聊天组件
    DevExtreme拥有高性能的HTML5/JavaScript小部件集合,使您可以利用现代Web开发堆栈(包括React,Angular,ASP.NETCore,jQuery,Knockout等)构建交互式的Web应用程序。从Angular和Reac,到ASP.NETCore或Vue,DevExtreme包含全面的高性能和响应式UI小部件集合,可在传统Web和下一代移动应用程序中......
  • 用js怎么实现图片马赛克效果?
    在前端JavaScript中,实现图片马赛克效果主要有两种方法:使用CanvasAPI和使用SVG滤镜。CanvasAPI更为常见和灵活,以下提供使用CanvasAPI实现马赛克效果的代码示例和详细解释:functionmosaic(image,tileSize){constcanvas=document.createElement('canvas');co......
  • css的加载会阻塞js运行吗?为什么?
    CSS的加载会阻塞DOM树的构建,从而间接阻塞依赖DOM结构的JavaScript代码的执行,但不会阻塞其他JavaScript代码的下载和解析。具体来说:浏览器渲染过程:浏览器渲染页面需要构建DOM树(描述HTML结构)和CSSOM树(描述CSS样式),然后合并成渲染树,最终绘制到屏幕上。CSS......
  • 在chrome中js的数组占用了多少内存?
    在Chrome中,JavaScript数组的内存占用取决于几个因素:数组元素的类型:这是影响最大的因素。基本类型(primitives):像数字(number),布尔值(boolean),空值(null),未定义(undefined)等,这些类型的值直接存储在数组中,占用空间相对固定。数字通常占用8字节(64......
  • 使用js生成1-10000的数组
    //Method1:Usingaforloop(mostcommonandgenerallyefficient)functiongenerateArray1(){constarr=[];for(leti=1;i<=10000;i++){arr.push(i);}returnarr;}//Method2:UsingArray.from()andkeys()(moreconcise)funct......
  • 你是如何排查js内存泄漏的?
    排查JavaScript内存泄漏是一个常见的前端性能优化任务。以下是一些常用的方法和工具:1.使用浏览器开发者工具:Memory标签页:这是ChromeDevTools中最常用的工具。HeapSnapshots:可以捕获JavaScript堆的快照,比较不同时间点的快照,找出哪些对象没有被垃圾回收,从而......
  • (免费源码)计算机毕业设计必学必看 万套实战教程 java、python、php、node.js、c#、APP
                   摘 要在网络信息的时代,众多的软件被开发出来,给业主带来了很大的选择余地,而且人们越来越追求更个性的需求。在这种时代背景下,智慧小区管理系统只能以业主为导向,以产品的持续创新作为智慧小区管理系统最重要的竞争手段。系统采用了B/S结构,将......