当前位置:首页 > VUE

vue node实现登录验证

2026-02-23 16:55:44VUE

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 服务器并设置路由:

vue node实现登录验证

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 对密码进行加密存储:

vue node实现登录验证

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'
  }
}

标签: vuenode
分享给朋友:

相关文章

拖拽式编程vue实现

拖拽式编程vue实现

拖拽式编程在 Vue 中的实现方法 使用 HTML5 原生拖放 API Vue 可以结合 HTML5 的拖放 API 实现基础拖拽功能。通过 draggable 属性标记可拖拽元素,监听 dragst…

vue实现录音文件播放

vue实现录音文件播放

使用 Vue 实现录音文件播放 准备工作 确保项目中已安装必要的依赖,如 vue-audio-recorder 或原生 Web Audio API。录音文件播放通常涉及录音、存储和播放三个核心环节。…

实现vue组件

实现vue组件

Vue 组件的基本实现 Vue 组件是 Vue.js 的核心特性之一,允许将 UI 拆分为独立、可复用的模块。以下是实现 Vue 组件的几种方式: 单文件组件 (SFC) 使用 .vue 文件格式,…

vue实现树

vue实现树

Vue 实现树形结构的方法 使用递归组件实现树形结构 递归组件是Vue中实现树形结构的常见方式。通过组件调用自身,可以轻松构建多层嵌套的树形数据。 <template> <ul…

vue实现datalist

vue实现datalist

使用 Vue 实现 HTML5 的 datalist 功能 HTML5 的 <datalist> 元素提供了一种自动完成输入框的功能,允许用户在输入时从预定义的选项列表中选择。以下是几种在…

vue实现烟花

vue实现烟花

Vue 实现烟花效果 在 Vue 中实现烟花效果可以通过结合 CSS 动画和 JavaScript 动态生成烟花元素。以下是具体实现方法: 动态生成烟花元素 通过 Vue 的 v-for 动…