当前位置: 首页 > news >正文

从零构建vue3项目(二)

Vue3项目增强配置:Axios封装、鉴权与代码扫描

1. Axios二次封装与拦截器配置

安装Axios

npm install axios

创建Axios实例 src/utils/request.js

import axios from 'axios'
import { useUserStore } from '@/stores/user'
import router from '@/router'// 创建axios实例
const service = axios.create({baseURL: import.meta.env.VITE_API_BASE_URL,timeout: 10000,headers: {'Content-Type': 'application/json;charset=utf-8'}
})// 请求拦截器
service.interceptors.request.use((config) => {const userStore = useUserStore()// 如果token存在,添加到请求头if (userStore.token) {config.headers.Authorization = `Bearer ${userStore.token}`}// 在这里可以添加全局参数if (config.method === 'get') {config.params = {...config.params,_t: Date.now() // 防止缓存}}return config},(error) => {return Promise.reject(error)}
)// 响应拦截器
service.interceptors.response.use((response) => {const res = response.data// 自定义状态码处理if (res.code !== 200) {// token过期if (res.code === 401) {const userStore = useUserStore()userStore.logout()router.push('/login?redirect=' + encodeURIComponent(router.currentRoute.value.fullPath))return Promise.reject(new Error(res.message || '登录状态已过期'))}// 其他错误return Promise.reject(new Error(res.message || 'Error'))} else {return res}},(error) => {// HTTP状态码处理if (error.response) {switch (error.response.status) {case 400:error.message = '请求错误'breakcase 401:error.message = '未授权,请重新登录'const userStore = useUserStore()userStore.logout()router.push('/login')breakcase 403:error.message = '拒绝访问'breakcase 404:error.message = '请求地址出错'breakcase 500:error.message = '服务器内部错误'breakdefault:error.message = `连接错误 ${error.response.status}`}} else if (error.request) {error.message = '服务器未响应'} else {error.message = '网络错误'}// 统一错误提示ElMessage.error(error.message)return Promise.reject(error)}
)export default service

使用示例 src/api/user.js

import request from '@/utils/request'export function login(data) {return request({url: '/auth/login',method: 'post',data})
}export function getUserInfo() {return request({url: '/user/info',method: 'get'})
}

2. Token鉴权集成

Pinia用户状态管理 src/stores/user.js

import { defineStore } from 'pinia'
import { login, logout, getUserInfo } from '@/api/user'
import { resetRouter } from '@/router'export const useUserStore = defineStore('user', {state: () => ({token: localStorage.getItem('token') || '',name: '',avatar: '',roles: []}),actions: {// 登录async login(userInfo) {const { username, password } = userInfotry {const res = await login({ username, password })this.token = res.tokenlocalStorage.setItem('token', res.token)return this.getInfo()} catch (error) {return Promise.reject(error)}},// 获取用户信息async getInfo() {try {const res = await getUserInfo()const { name, avatar, roles } = resthis.name = namethis.avatar = avatarthis.roles = rolesreturn res} catch (error) {return Promise.reject(error)}},// 登出async logout() {try {await logout()} finally {this.token = ''this.roles = []localStorage.removeItem('token')resetRouter()}}}
})

路由守卫 src/router/permission.js

import router from './index'
import { useUserStore } from '@/stores/user'
import { ElMessage } from 'element-plus'const whiteList = ['/login'] // 不重定向白名单router.beforeEach(async (to, from, next) => {const userStore = useUserStore()// 确定用户是否已登录if (userStore.token) {if (to.path === '/login') {next({ path: '/' })} else {// 检查用户是否已获取角色信息if (userStore.roles.length === 0) {try {await userStore.getInfo()// 动态生成可访问路由const accessRoutes = await generateRoutes(userStore.roles)accessRoutes.forEach(route => {router.addRoute(route)})next({ ...to, replace: true })} catch (error) {// 获取用户信息失败,重定向到登录页userStore.logout()ElMessage.error(error || '验证失败,请重新登录')next(`/login?redirect=${to.path}`)}} else {next()}}} else {if (whiteList.includes(to.path)) {next()} else {next(`/login?redirect=${to.path}`)}}
})

3. 代码扫描工具集成

SonarQube配置 (可选)

.sonarcloud.properties:

sonar.projectKey=my-vue3-app
sonar.organization=your-org
sonar.host.url=https://sonarcloud.io
sonar.login=your-sonar-tokensonar.sources=src
sonar.tests=src
sonar.test.inclusions=**/*.spec.js,**/*.test.js
sonar.javascript.lcov.reportPaths=coverage/lcov.info
sonar.exclusions=**/node_modules/**,**/dist/**,**/coverage/**,**/public/**,**/*.config.js

添加扫描脚本 package.json

{"scripts": {"sonar": "sonar-scanner","test:coverage": "vitest run --coverage","lint:ci": "eslint . --ext .vue,.js,.jsx,.ts,.tsx --format json --output-file eslint-report.json"}
}

GitHub Action集成 .github/workflows/code-analysis.yml

name: Code Analysis
on:push:branches: [ main ]pull_request:branches: [ main ]jobs:analysis:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v2- name: Set up Node.jsuses: actions/setup-node@v2with:node-version: '16'- name: Install dependenciesrun: npm install- name: Run tests with coveragerun: npm run test:coverage- name: Run linterrun: npm run lint:ci- name: SonarCloud Scanuses: SonarSource/sonarcloud-github-action@v1env:GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

4. 安全增强配置

CSP配置 vite.config.js

import { defineConfig } from 'vite'export default defineConfig({// ...其他配置server: {headers: {'Content-Security-Policy': "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;"}}
})

Helmet中间件 (Node.js后端)

const helmet = require('helmet')app.use(helmet({contentSecurityPolicy: {directives: {defaultSrc: ["'self'"],scriptSrc: ["'self'", "'unsafe-inline'"],styleSrc: ["'self'", "'unsafe-inline'"],imgSrc: ["'self'", "data:"]}},hsts: {maxAge: 63072000,includeSubDomains: true,preload: true}
}))

5. 完整增强后的项目结构

my-vue3-app/
├── src/
│   ├── api/                  # API接口
│   │   ├── user.js           # 用户相关API
│   │   └── ...               # 其他模块API
│   ├── router/
│   │   ├── index.js          # 基础路由
│   │   ├── permission.js     # 路由守卫
│   │   └── modules/          # 动态路由模块
│   ├── stores/
│   │   ├── index.js          # Pinia主文件
│   │   ├── user.js           # 用户状态
│   │   └── ...               # 其他状态模块
│   ├── utils/
│   │   ├── request.js        # Axios封装
│   │   └── auth.js           # 鉴权工具
├── .sonarcloud.properties    # SonarQube配置
├── .github/workflows/        # CI/CD配置
└── ...                       # 其他原有文件

6. 关键点说明

  1. Axios封装特点

    • 统一错误处理机制
    • 自动Token注入
    • 防止GET请求缓存
    • 响应数据统一格式处理
  2. 鉴权系统特点

    • JWT Token存储与自动更新
    • 动态路由权限控制
    • 路由守卫保护
    • 角色基础权限系统
  3. 代码扫描集成

    • 本地SonarQube扫描支持
    • CI/CD流水线集成
    • 测试覆盖率报告
    • 静态代码分析
  4. 安全增强

    • CSP内容安全策略
    • HTTPS严格传输安全
    • XSS防护头
    • CSRF令牌支持(后端需配合)

这套配置提供了企业级Vue3应用所需的核心安全、鉴权和代码质量保障功能,可以根据项目实际需求进行适当调整。

http://www.lryc.cn/news/575632.html

相关文章:

  • 机器学习在智能农业中的创新应用与未来趋势
  • 永磁无刷电机旋转原理
  • 进程和线程的区别?
  • 128.最长连续序列
  • 本地开发Anchor智能合约:效率翻倍的秘密
  • windows下 tomcat的安装部署
  • 机器学习17-发展历史补充
  • 第一章-人工智能概述-机器学习基础与应用(1/36)
  • spring-ai 1.0.0 (1)模型调用能力
  • day43 复习日(猫狗图像分类)
  • 算法第48天|单调栈:42. 接雨水、84.柱状图中最大的矩形
  • 从零开始理解百度语音识别API的Python实现
  • 抖音图文带货和短视频带货有什么区别
  • 深入解析设备管理系统新趋势:物联网与云原生驱动的智能化实践
  • OpenBayes 一周速览丨Nanonets-OCR-s深度语义理解,精准结构化转换;HLE人类问题推理基准上线,含2.5k题目,助力封闭式评估体系构建
  • COZE API上传文件 直接从前端发送就可以,而通过后端发请求给CozeAPI就不行,为什么?
  • 【百日精通JAVA | 数据结构篇】 一文了解泛型体系
  • 新手向:Anaconda3的安装与使用方法
  • AMS流媒体服务器-新版(h265-flv)
  • FFMpeg的AVFrame数据格式解析
  • IDE如何快速切换JLINK版本
  • vue 开启 source-map 后构建速度会很慢
  • Android杂谈(一):悬浮球
  • 随记:WebMvcConfigurationSupport 和WebMvcConfigurer 的区别
  • DevSecOps时代下测试工具的全新范式:从孤立到融合的质变之路
  • ubuntu22.04系统kubeadm部署k8s高可用集群
  • 伏羲微官网企业建站授权证书/防伪查询/三合一应用【前端开源】
  • 2D写实交互数字人如何重塑服务体验?
  • [特殊字符] Windows 查看端口占用及服务来源教程(以 9018 端口为例)
  • TCP 重传机制详解:原理、变体与故障排查应用