今天將為個人財務管理應用實現用戶註冊和登入功能,並透過 JWT (JSON Web Token) 進行身份驗證。這是應用安全性的重要一環,能確保只有經過驗證的用戶可以進行相關操作。
首先,要為用戶設置一個基本模型,來存儲用戶的帳號、密碼等基本訊息。接下來將使用 Mongoose 建立 User.js 模型。
在 models/ 文件夾中創建 User.js:
js
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const userSchema = new mongoose.Schema({
username: { type: String, required: true, unique: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
});
// 密碼加密
userSchema.pre('save', async function (next) {
if (!this.isModified('password')) return next();
const salt = await bcrypt.genSalt(10);
this.password = await bcrypt.hash(this.password, salt);
next();
});
module.exports = mongoose.model('User', userSchema);
接著,實現用戶的註冊功能。用戶註冊時,會創建一個新帳號並將密碼加密後儲存。此過程會使用 bcryptjs 進行密碼加密。
在 routes/ 文件夾中創建 auth.js,並設置註冊路由:
js
const express = require('express');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const User = require('../models/User');
const router = express.Router();
// 註冊路由
router.post('/register', async (req, res) => {
const { username, email, password } = req.body;
try {
// 檢查用戶是否已經存在
let user = await User.findOne({ email });
if (user) {
return res.status(400).json({ msg: 'User already exists' });
}
// 創建新用戶
user = new User({ username, email, password });
await user.save();
// 生成 JWT
const payload = { userId: user._id };
const token = jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: '1h' });
res.status(201).json({ token });
} catch (error) {
res.status(500).json({ msg: 'Server error' });
}
});
module.exports = router;
在這裡,我們首先檢查用戶是否已經註冊過,然後創建一個新用戶,將密碼進行加密儲存,最後生成一個有效期為 1 小時的 JWT,並返回給用戶。
登入功能允許用戶使用已註冊的憑據登錄系統。登入後,系統會生成一個 JWT,並將其返回給用戶作為身份驗證的憑證。
繼續在 auth.js 中添加登入程式碼:
js
// 登入路由
router.post('/login', async (req, res) => {
const { email, password } = req.body;
try {
// 檢查用戶是否存在
const user = await User.findOne({ email });
if (!user) {
return res.status(400).json({ msg: 'Invalid credentials' });
}
// 檢查密碼
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) {
return res.status(400).json({ msg: 'Invalid credentials' });
}
// 生成 JWT
const payload = { userId: user._id };
const token = jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: '1h' });
res.json({ token });
} catch (error) {
res.status(500).json({ msg: 'Server error' });
}
});
這段程式碼會首先驗證用戶輸入的電子郵件和密碼是否正確,如果成功,則會生成一個新的 JWT,讓用戶登入。
為了確保只有已登入的用戶能夠進行某些操作,使用 JWT 來保護後端 API 是至關重要的。
在 middleware/ 文件夾中創建 authMiddleware.js,用於驗證 JWT:
js
const jwt = require('jsonwebtoken');
module.exports = function (req, res, next) {
const token = req.header('Authorization');
if (!token) {
return res.status(401).json({ msg: 'No token, authorization denied' });
}
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded.userId;
next();
} catch (err) {
res.status(401).json({ msg: 'Token is not valid' });
}
};
這個中間軟體會檢查請求中的 Authorization 標頭是否包含 JWT,然後解碼該 token 並將用戶 ID 傳遞到後續處理邏輯中。
在 server.js 中整合新創建的路由,讓 Express 能夠處理註冊與登入請求:
js
const authRoutes = require('./routes/auth');
app.use('/api/auth', authRoutes);
接著,使用 Postman 或其他 API 測試工具,測試註冊與登入功能是否運行正常:
今天實現了用戶的註冊和登入功能,並透過 JWT 驗證來保護應用的 API,也學習了如何加密用戶密碼,並生成安全的 JSON Web Token,這些功能就可以保障使用者的安全。在接下來的開發中,將繼續利用這些技術來進一步保護和構建應用。