vue node实现登录验证
Vue 和 Node.js 实现登录验证
前端部分 (Vue)
安装必要的依赖,如 axios 用于发送 HTTP 请求:
npm install axios
创建登录表单组件,包含用户名和密码输入框:
<template>
<form @submit.prevent="handleLogin">
<input v-model="username" type="text" placeholder="Username">
<input v-model="password" type="password" placeholder="Password">
<button type="submit">Login</button>
</form>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
username: '',
password: ''
}
},
methods: {
async handleLogin() {
try {
const response = await axios.post('http://localhost:3000/login', {
username: this.username,
password: this.password
});
localStorage.setItem('token', response.data.token);
this.$router.push('/dashboard');
} catch (error) {
console.error('Login failed:', error);
}
}
}
}
</script>
后端部分 (Node.js)
安装必要的依赖:
npm install express body-parser jsonwebtoken bcryptjs
创建 Express 服务器并设置路由:
const express = require('express');
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const app = express();
app.use(bodyParser.json());
const users = []; // 临时存储用户数据,实际项目中应使用数据库
app.post('/register', async (req, res) => {
try {
const hashedPassword = await bcrypt.hash(req.body.password, 10);
const user = { username: req.body.username, password: hashedPassword };
users.push(user);
res.status(201).send();
} catch {
res.status(500).send();
}
});
app.post('/login', async (req, res) => {
const user = users.find(user => user.username === req.body.username);
if (user == null) return res.status(400).send('Cannot find user');
try {
if (await bcrypt.compare(req.body.password, user.password)) {
const token = jwt.sign({ username: user.username }, 'secret_key');
res.json({ token });
} else {
res.status(403).send('Not Allowed');
}
} catch {
res.status(500).send();
}
});
app.listen(3000, () => console.log('Server running on port 3000'));
验证保护路由
在前端添加路由守卫:
// router.js
import Vue from 'vue';
import Router from 'vue-router';
import Dashboard from './views/Dashboard.vue';
import Login from './views/Login.vue';
Vue.use(Router);
const router = new Router({
routes: [
{ path: '/', redirect: '/login' },
{ path: '/login', component: Login },
{
path: '/dashboard',
component: Dashboard,
meta: { requiresAuth: true }
}
]
});
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
if (!localStorage.getItem('token')) {
next('/login');
} else {
next();
}
} else {
next();
}
});
export default router;
在后端添加中间件验证 JWT:
function authenticateToken(req, res, next) {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];
if (token == null) return res.sendStatus(401);
jwt.verify(token, 'secret_key', (err, user) => {
if (err) return res.sendStatus(403);
req.user = user;
next();
});
}
app.get('/protected', authenticateToken, (req, res) => {
res.json({ message: 'Protected data', user: req.user });
});
密码加密
使用 bcrypt 对密码进行加密存储:
const saltRounds = 10;
const hashedPassword = await bcrypt.hash(plainPassword, saltRounds);
令牌刷新
实现令牌刷新机制:
app.post('/token', (req, res) => {
const refreshToken = req.body.token;
if (refreshToken == null) return res.sendStatus(401);
jwt.verify(refreshToken, 'refresh_secret', (err, user) => {
if (err) return res.sendStatus(403);
const accessToken = jwt.sign({ username: user.username }, 'secret_key', { expiresIn: '15m' });
res.json({ accessToken });
});
});
跨域问题解决
在 Node.js 中启用 CORS:
const cors = require('cors');
app.use(cors());
或在 Vue 中配置代理:
// vue.config.js
module.exports = {
devServer: {
proxy: 'http://localhost:3000'
}
}






