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

基于flask+jwt+vue前后端分离架构

        基于 Flask、JWT 和 Vue 的前后端分离架构是一种现代且流行的开发方式,它允许前端和后端独立开发、部署和扩展。以下是一个基本的实现步骤和示例代码,帮助你快速搭建这样的架构。

 后端(flask+jwt)

安装依赖

pip install Flask Flask-JWT-Extended

创建 Flask 应用

创建一个简单的 Flask 应用,包括用户注册、登录和受保护的路由。

from flask import Flask,jsonify,request
from flask_jwt_extended import JWTManager,create_access_token,jwt_required,get_jwt_identity
from flask_cors import CORS
app=Flask(__name__)
app.config['JWT_SECRET_KEY']='123456'
jwt=JWTManager(app)
CORS(app)

@app.route('/login',methods=['POST'])
def login():
    username=request.json.get('username',None)
    password=request.json.get('password',None)

    if username!='admin' or password !='password':
        return jsonify({"msg":"bad name or password"})
    access_token=create_access_token(identity=username)
    return jsonify(access_token=access_token)
#受保护的路由
@app.route('/protected',methods=['GET'])
@jwt_required()
def protected():
    current_user=get_jwt_identity()
    return jsonify(logged_in_as=current_user),200

if __name__=='__main__':
    app.run(debug=True)

前端(Vue)

安装 Vue CLI

如果你还没有安装 Vue CLI,可以通过以下命令安装:

npm install -g @vue/cli

创建 Vue 项目

创建一个新的 Vue 项目:

vue create my-vue-app
cd my-vue-app

安装 Axios

Axios 是一个基于 Promise 的 HTTP 客户端,用于浏览器和 node.js。

npm install axios

创建 Vue 组件和服务

在 src 目录下,创建一些基本的组件和服务来处理登录、注册和受保护的请求。

src/services/authService.js

import axios from 'axios';

const API_URL = 'http://127.0.0.1:5000';  // 后端 API 地址

const register = async (username, password) => {
    const response = await axios.post(`${API_URL}/register`, { username, password });
    return response.data;
};

const login = async (username, password) => {
    const response = await axios.post(`${API_URL}/login`, { username, password });
    localStorage.setItem('token', response.data.access_token);
    return response.data;
};

const getToken = () => {
    return localStorage.getItem('token');
};

const setHeaders = (axiosInstance) => {
    axiosInstance.interceptors.request.use(
        config => {
            const token = getToken();
            if (token) {
                config.headers['Authorization'] = `Bearer ${token}`;
            }
            return config;
        },
        error => {
            return Promise.reject(error);
        }
    );
};

const axiosInstance = axios.create();
setHeaders(axiosInstance);

const getProtectedResource = async () => {
    const response = await axiosInstance.get(`${API_URL}/protected`);
    return response.data;
};

export { register, login, getProtectedResource };

创建Login, Proteced组件

src/components/Login.vue

<template>
  <div>
    <h2>Login</h2>
    <form @submit.prevent="loginUser">
      <div>
        <label for="username">Username:</label>
        <input type="text" v-model="username" required />
      </div>
      <div>
        <label for="password">Password:</label>
        <input type="password" v-model="password" required />
      </div>
      <button type="submit">Login</button>
    </form>
  </div>
</template>

<script>
import { login } from '../services/authService';

export default {
  data() {
    return {
      username: '',
      password: ''
    };
  },
  methods: {
    async loginUser() {
      try {
        const response = await login(this.username, this.password);
        alert('Login successful');
        // 你可以在这里重定向到受保护的页面或其他逻辑
      } catch (error) {
        alert('Login failed');
      }
    }
  }
};
</script>

src/components/Protected.vue

<template>
  <div>
    <h2>Protected Resource</h2>
    <div v-if="loading">Loading...</div>
    <div v-else-if="error">{{ error }}</div>
    <div v-else>
      <p>Logged in as: {{ user }}</p>
    </div>
  </div>
</template>

<script>
import { getProtectedResource } from '../services/authService';

export default {
  data() {
    return {
      user: null,
      loading: true,
      error: null
    };
  },
  created() {
    this.fetchProtectedResource();
  },
  methods: {
    async fetchProtectedResource() {
      try {
        const response = await getProtectedResource();
        this.user = response.logged_in_as;
      } catch (error) {
        this.error = 'Failed to fetch protected resource';
      } finally {
        this.loading = false;
      }
    }
  }
};
</script>

src/App.vue

<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'App'
};
</script>

创建路由组件

src/router/index.js

import Vue from 'vue';
import {createRouter, createWebHistory} from 'vue-router'
import Login from '@/components/Login.vue';
import Protected from '@/components/Protected.vue';

Vue.use(Router);
const  routes:=[
    {
      path: '/',
      name: 'Login',
      component: Login
    },
    {
      path: '/protected',
      name: 'Protected',
      component: Protected,
      meta: { requiresAuth: true }
    }
  ]

const router = createRouter({
  history: createWebHistory(),
  routes
})

// 路由守卫,检查token
router.beforeEach((to, from, next) => {
  const token = localStorage.getItem('token');
  if (to.matched.some(record => record.meta.requiresAuth) && !token) {
    next('/login');
  } else {
    next();
  }
})

export default router

前端main代码

src/main.js

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

createApp(App).use(router).mount('#app')


http://www.kler.cn/a/392961.html

相关文章:

  • RTOS 基础知识
  • 实战分享:开发设计文档模版及编写要点
  • 使用C#生成一张1G大小的空白图片
  • 机器学习之PCA降维
  • FreeSql
  • KAFKA 权威指南笔记(一)究竟应该配置多少个BROKER?
  • 如何提高业务系统的稳定性
  • 浅谈C#之内存管理
  • 【无人机设计与控制】无人机集群路径规划:5种最新优化算法(ECO、AOA、SFOA、MGO、PLO)求解无人机集群路径规划
  • 鸿蒙学习生态应用开发能力全景图-三方库(3)
  • 专题十八_动态规划_斐波那契数列模型_路径问题_算法专题详细总结
  • C语言中操作符详解(下)
  • MFC工控项目实例二十九主对话框调用子对话框设定参数值
  • 当微软windows的记事本被AI加持
  • 定时清理潜在客户列表中的无效邮箱可提高EDM电子邮件自动化营销邮件送达率
  • Android插件化和组件化面试题及参考答案
  • Mac的极速文件搜索工具,高效管理文件
  • 时序数据库TimescaleDB安装部署以及常见使用
  • 手机直连卫星NTN通信初步研究
  • WPF+MVVM案例实战与特效(二十八)- 自定义WPF ComboBox样式:打造个性化下拉菜单
  • ArkTS的进阶语法-4(函数补充,正则表达式)
  • 【嵌入式开发】单片机CAN配置详解
  • 【QT】解决生成的exe文件出现“无法定位程序入口”或“找不到xxx.dll”的问题
  • PHP中小学优校管理系统小程序源码
  • Unity学习笔记(4):人物和基本组件
  • flume采集netcat数据到kafka指定主题