从零构建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.pswp.cn/pingmian/86505.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/86505.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

哪家香港站群服务器比较好用?

面对鱼龙混杂的服务商市场,哪家的香港站群服务器真正稳定?毕竟搞站群最怕的就是服务器抽风,轻则掉排名,重则客户跑光光。今天咱就重点聊聊哪家香港站群服务器比较好用? 一般来说,在选择香港站群服务器提供…

Python的科学计算库NumPy(二)

5. 索引和切片 5.1 一维数组的索引和切片 import numpy as np# 一维数组索引和切片,跟python中的集合同样使用 bin_list[1,2,3,4,5,6] bin_arraynp.array(bin_list) print(bin_array[3]) print(bin_array[1:4]) print(bin_array[-2:-1])5.2 多维数组的索引 # 多维…

STM32和C++ 实现配置文件导入、导出功能

一.配置文件导出功能 // 导出流程 // 1. 客户端 → 设备:导出配置请求,例如:GetFlashData[d6fe30323454]:{ini} ,其中[]里面是设备序列号 // 2. 设备 → 客户端:配置文件元数据(总大小、块数量) // 3. 设备 → 客户端:发送块1(包含块序号和大小) // 4. 设备 → 客户端:…

HTTP 请求基础知识

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言HTTP 请求方法GETPOSTPUTDELETE其他方法 HTTP 请求结构常用请求头实际应用示例响应状态码 前言 HTTP (Hypertext Transfer Protocol) 是互联网上应用最广泛的协…

Django ORM 1. 创建模型(Model)

1. ORM介绍 什么是ORM? ORM,全称 Object-Relational Mapping(对象关系映射),一种通过对象操作数据库的技术。 它的核心思想是:我们不直接写 SQL,而是用 Python 对象(类/实例&…

【C/C++】C++ 编程规范:101条规则准则与最佳实践

C 编程规范:101条规则准则与最佳实践 引言 C 是一门强大而复杂的语言,能高效控制硬件,也能写出优雅抽象。然而,正因其复杂性,项目中若缺乏统一规范,极易陷入混乱、难维护、易出错的泥潭。 本文总结了 10…

柔性屏激光修屏禁区突破:新启航如何实现曲面 OLED 面板的无损修复?

一、引言 柔性 OLED 面板凭借其轻薄、可弯曲等特性,在智能终端、可穿戴设备等领域广泛应用。然而,生产过程中面板易出现缺陷,传统修复方法难以满足曲面 OLED 面板的无损修复需求。新启航半导体有限公司在激光修屏技术上取得突破,…

UI前端与数字孪生结合案例分享:智慧零售的可视化解决方案

hello宝子们...我们是艾斯视觉擅长ui设计、前端开发、数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩! 一、引言:智慧零售的可视化变革 在数字化浪潮下,零售行业正从 “人货场…

Docker 入门教程(四):容器命令

文章目录 🐳 Docker 入门教程(四):容器命令创建并运行容器:docker run查看容器列表:docker ps停止、启动、重启容器删除容器:docker rm进入容器:exec 和 attach查看容器日志&#xf…

2025.06.27【技术观察L0】AlphaGenome:DeepMind推出的全新AI基因组解读平台

AlphaGenome:DeepMind推出的全新AI基因组解读平台详解 2025年6月,Google DeepMind团队正式发布了AlphaGenome——一款面向基因组功能解读和变异效应预测的全新人工智能模型。AlphaGenome的出现,标志着AI在基因组学领域迈出了重要一步&#x…

[ARM-2D 专题]7. OOP实现之继承,宏implement_ex的实现和解析

implement_ex宏是 Arm-2D 库中用于面向对象编程(OOP)支持的核心宏定义。 implement_ex 宏的定义和作用 implement_ex 宏在 Library/Include/arm_2d_utils.h 中定义,用于在 C 语言中实现类似继承的功能: /*!* \note do NOT use t…

默认构造函数

1、构造函数 一、什么是构造函数 c中有一种特殊的成员函数,他的名字和类名相同,没有返回值,而在创建对象时会自动执行,类中的数据成员的初始化往往通过构造函数来实现。完成类中数据成员的初始化,同时也是类中的成员…

带标签的 Docker 镜像打包为 tar 文件

现在还有人用docker吗 要将带标签的 Docker 镜像打包为 tar 文件,请使用 docker save 命令。以下是详细操作指南: 一、单镜像打包(推荐方式) # 基础格式 docker save -o [输出文件名].tar [镜像名]:[标签]# 示例:将…

基于GPS-RTK的履带吊车跑偏检测技术方案

基于GPS-RTK的履带吊车跑偏检测技术方案 1. 引言 1.1 项目背景 履带吊车作为重型工程机械,其行驶稳定性直接关系到作业安全和设备寿命。跑偏现象会导致履带异常磨损、转向系统过载,严重时可能引发侧翻事故。传统检测方法(如激光测距或人工观…

勾正数据大数据开发面试题整理-20250625

最近面了家公司,想看看自己多年不准备面试,靠着老本能面试成啥样,算是试试水吧,一面过了,二面有个算法题没答出来,整体答得状态也不太好,应该是没过。 一面 先来说说一面吧,一面是…

基于中国香港会计准则差异,中国企业在香港推广ERP(SAP、Oracle)系统需要注意的细节

核心在于:ERP通常按单一会计准则设计主数据架构,但跨国企业需要同时满足两地报表要求。 用户常见的场景包括: 1 科目体系能否同时承载CAS的专项储备和HKFRS的禁止计提? 2 资产模块如何兼容不同的减值转回规则? 3 关联…

【编译原理】期末复习知识总结

目录 题型 总结 编译五大组成部分 编译与解释方式区别? 前端,后端,Why? 概念 推导、归约 短语、简单短语、句柄 文法 分类 正则文法(3型) NFA、DFA、最小化 自上而下语法分析(推导…

【软考高级系统架构论文】论微服务架构及其应用

论文真题 论微服务架构及其应用近年来,随着互联网行业的迅猛发展,公司或组织业务的不断扩张,需求的快速变化以及用户量的不断增加,传统的单块(Monolithic) 软件架构面临着越来越多的挑战,已逐渐无法适应互联网时代对软件的要求。在这一背景下,微服务架构模式(Microservi…

【人工智能】RAG分块

在RAG(检索增强生成)系统中,文档分块(Chunking)是决定系统性能的核心环节,直接影响检索精度和生成质量。分块需平衡语义完整性、检索效率和上下文保留三大目标。 一、分块的核心标准 1.1 分块基础知识​ …

能耗管理新革命:物联网实现能源高效利用

在全球能源危机与 “双碳” 目标的双重压力下,企业与社会对能耗管理的重视程度达到前所未有的高度。然而,传统能耗管理方式存在数据采集滞后、分析维度单一、节能措施粗放等问题,无法满足精细化管理需求。物联网技术凭借其强大的数据感知、传…