一、创建项目结构
前端Vue-cli
后端Express
(1)安装express-generator
1
| npm install express-generator -g
|
(2) 创建express
项目工程
1 2 3 4
| express -e 项目名 cd 项目名 npm install npm install express mongoose bcryptjs jsonwebtoken cors body-parser
|
二、创建数据库
1、先创建集合,然后插入数据
2、创建文件夹db/index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| const mongoose = require('mongoose')
mongoose.set("strictQuery", false);
module.exports = function (success, error) { if (typeof error !== 'function') { error = () => { console.log('链接失败') } } mongoose.connect('mongodb://127.0.0.1:27017/email') mongoose.connection.on('open', () => { success() }) mongoose.connection.on('error', () => { error() }) mongoose.connection.on('close', () => { console.log('链接关闭') }) }
|
3、在启动bin/www 下面链接数据库
三、创建前端登录和注册页面
前端登录组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| <template> <div class="login-page"> <!-- 登录页面 --> <div class="login"> <div class="login-box"> <!-- <div class="login-title">登录</div> --> <form> <div class="form-group clearfix"> <label for="username" class="leftfix" ><img src="../../assets/img/denglu-copy.png" alt="" /></label> <input type="text" class="leftfix" id="username" name="username" placeholder="请输入用户名" v-model="username" /> </div> <div class="form-group clearfix"> <label for="password" class="leftfix" ><img src="../../assets/img/mima.png" alt="" /></label > <input type="password" class="leftfix" id="password" name="password" placeholder="请输入密码" v-model="password" /> </div> <div class="login-bottom"> <input type="button" class="btn-login" value="登录" @click="login" /> <label> <input type="checkbox" checked="checked" />记住密码 </label> <label> <router-link to="/register">注册账号</router-link> </label> </div> </form> </div> </div> </div> </template>
|
前端注册组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <template> <div class="container"> <div class="registration-form"> <h2>用户注册</h2> <form @submit.prevent="register"> <div class="form-group"> <label for="username">用户名</label> <input type="text" id="username" v-model="userData.username" required placeholder="请输入用户名" /> </div> <div class="form-group"> <label for="password">密码</label> <input type="password" id="password" v-model="userData.password" required placeholder="请输入密码" style="margin-left: 33px" /> </div> <button type="submit" @click="register">注册</button> </form> </div> </div> </template>
|
四、后端逻辑
4.1.登录
1、新创建一个models文件夹,然后在下面创建一个UserModel.js
1 2 3 4 5 6 7 8 9
| var mongoose = require('mongoose')
let userSchema = new mongoose.Schema({ username: String, password: String, })
let UserModel = mongoose.model('users', userSchema) module.exports = UserModel
|
2、定义登录
路由和处理逻辑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| const express = require('express'); const router = express.Router(); const bcrypt = require('bcryptjs'); const jwt = require('jsonwebtoken'); const UserModel = require('../models/UserModel');
router.post('/login', async (req, res) => { const { username, password } = req.body; try { const user = await UserModel.findOne({ username });
if (!user) { return res.status(404).json({ message: '用户不存在' }); }
const isPasswordValid = await bcrypt.compare(password, user.password);
if (!isPasswordValid) { return res.status(401).json({ message: '密码不正确' }); }
const token = jwt.sign({ userId: user._id, username: user.username }, 'secretKey', { expiresIn: '1h', });
res.status(200).json({ token }); } catch (err) { console.error(err); res.status(500).json({ message: '服务器错误' }); } }); module.exports = router;
|
3、新创建一个middleware文件夹,然后在下面创建一个auth.js
创建一个中间件来验证用户的身份
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| const jwt = require('jsonwebtoken');
function generateToken(username) { const secretKey = 'your-secret-key';
const payload = { username: username };
const token = jwt.sign(payload, secretKey, { expiresIn: '1d' });
return token; }
module.exports.generateToken = generateToken;
module.exports.verifyToken = function (req, res, next) { const token = req.header('x-auth-token');
next(); };
|
4、分离路由 和 设置前缀
app.js中
4.2 注册
1、定义注册
路由和处理逻辑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| const express = require('express'); const router = express.Router(); const bcrypt = require('bcryptjs'); const jwt = require('jsonwebtoken'); const UserModel = require('../models/UserModel');
router.post('/register', async (req, res) => { const { username, password } = req.body;
try { const existingUser = await UserModel.findOne({ username });
if (existingUser) { return res.status(400).json({ message: '用户名已存在' }); }
const saltRounds = 10; const hashedPassword = await bcrypt.hash(password, saltRounds);
const newUser = new UserModel({ username, password: hashedPassword });
await newUser.save();
const payload = { username: newUser.username };
const token = jwt.sign(payload, 'secretKey', { expiresIn: '1d' });
res.json({ token }); } catch (error) { console.error(error); res.status(500).json({ message: '服务器错误' }); } });
module.exports = router;
|
2、分离路由 和设置前缀
同上
五、前端逻辑
登录
在前端,使用Axios库来发送HTTP请求到后端。在 Login.vue
和 Register.vue
组件中添加数据绑定、表单验证、事件处理以及Axios请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| <script> import axios from "axios";
export default { data() { return { username: "", password: "", }; }, name: "loginPage", methods: { async login() { const response = await axios .post("http://localhost:3000/users/login", { username: this.username, password: this.password, }) .then((res) => { console.log("res", res); const token = res.data.token;
localStorage.setItem("token", token); this.$router.push("/indexMain"); }) .catch((err) => { this.$message.error(err.response.data); }); }, }, }; </script>
|
注册
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| <script> import axios from "axios"; export default { data() { return { userData: { username: "", password: "", }, isRegistering: false, }; }, name: "register", methods: { async register() { if (this.isRegistering) { return; } this.isRegistering = true; const response = await axios .post("http://localhost:3000/register/register", { username: this.userData.username, password: this.userData.password, }) .then((res) => { const token = res.data.token; localStorage.setItem("token", token);
this.$router.push("/login"); }) .catch((err) => { this.$message.error(err.response.data); }) .finally(() => { this.isRegistering = false; }); }, }, }; </script>
|