📅  最后修改于: 2023-12-03 15:09:43.175000             🧑  作者: Mango
本文章将介绍如何在 Node.js、Express 和 MongoDB 中使用 JWT 实现用户认证和授权的样板。
JWT,即 JSON Web Token,是一种用于在 Web 应用程序之间安全地传输信息的开放标准。JWT 包含三部分信息:头部、声明和签名,其 payload 可与自定义数据一起使用。
本样板采用了 Node.js、Express 和 MongoDB 技术栈,主要用于实现用户认证和授权功能。它提供了基本的用户注册、登录和访问控制功能,并使用 JWT 进行身份验证。
在开始使用本样板前,您需要具备以下技术:
您可以在 GitHub 上下载本样板。
$ git clone https://github.com/someone/sample-jwt-express-mongo.git
进入项目根目录并安装依赖。
$ cd sample-jwt-express-mongo
$ npm install
本样板使用 dotenv 库实现环境变量管理。首先,将 .env.example
文件重命名为 .env
,然后打开文件并设置变量的值。
PORT=3000
MONGO_URI=mongodb://localhost/sample-jwt-express-mongo
JWT_SECRET=your-secret-key
PORT
是您的应用程序将要监听的端口。MONGO_URI
是您的 MongoDB 连接字符串。JWT_SECRET
是您用于签名令牌的秘密密钥。
使用以下命令启动应用程序。
$ npm start
sample-jwt-express-mongo/
├── config/
│ └── auth.js
├── controllers/
│ ├── auth.js
│ └── user.js
├── middleware/
│ └── auth.js
├── models/
│ └── user.js
├── routes/
│ ├── auth.js
│ └── user.js
├── app.js
├── package.json
├── .env
└── README.md
用户注册
用户注册的路由是 /api/auth/register
。通过 POST 方法提交用户名和密码。如果注册成功,将返回包含新创建的用户对象的 JSON 有效负载。
router.post('/register', async (req, res) => {
try {
const { username, password } = req.body
const user = new User({ username, password })
await user.save()
const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET)
res.json({
success: true,
token: token,
user: { id: user._id, username: user.username }
})
} catch (err) {
console.error(err)
res.status(500).json({ success: false, message: 'Internal server error' })
}
})
用户登录
用户登录的路由是 /api/auth/login
。通过 POST 方法提交用户名和密码。如果登录成功,将返回令牌和用户对象的 JSON 有效负载。
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: 'Invalid credentials' })
const isMatch = await user.comparePassword(password)
if (!isMatch) return res.status(401).json({ success: false, message: 'Invalid credentials' })
const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET)
res.json({
success: true,
token: token,
user: { id: user._id, username: user.username }
})
} catch (err) {
console.error(err)
res.status(500).json({ success: false, message: 'Internal server error' })
}
})
实现访问控制需要使用身份验证中间件。
const authMiddleware = async (req, res, next) => {
try {
const token = req.headers.authorization.split(' ')[1]
const payload = jwt.verify(token, process.env.JWT_SECRET)
const user = await User.findById(payload.id)
req.user = { id: user._id, username: user.username }
next()
} catch (err) {
console.error(err)
res.status(401).json({ success: false, message: 'Unauthorized' })
}
}
使用身份验证中间件
您可以将身份验证中间件应用于需要保护的所有路由或某些路由。
将身份验证中间件应用于所有路由:
// app.js
app.use('/api', authMiddleware, apiRouter)
将身份验证中间件应用于某些路由:
// routes/user.js
router.get('/me', authMiddleware, async (req, res) => {
res.json({ success: true, user: req.user })
})