所有文章 > API开发 > vue3 实现简单页面登录,fastapi + mysql 前后端分离,pinia登录状态持久化
vue3 实现简单页面登录,fastapi + mysql 前后端分离,pinia登录状态持久化

vue3 实现简单页面登录,fastapi + mysql 前后端分离,pinia登录状态持久化

1.Vue3登录页面

相对于昨天的代码,登录部分主要是修改了login的代码:

const login = () => {

const user = {
username: Login.loginName,
password: Login.password
}

axios.post('http://localhost:4321/login', {
username: Login.loginName,
password: Login.password
},{
headers: {
'Content-Type': 'application/json'
}},
{ withCredentials: true }
)
.then(response => {
console.log(Login)
const { data } = response
if (data.message === 'Login successful') {
//router.push('/dashboard')
ElMessage({
message: '恭喜,登录成功!',
type: 'success',
})
router.push('/dashboard')
} else {
ElMessage({
message: '登录失败,请检查用户名和密码!',
type: 'error',
})
}
})
.catch(error => {
console.error('登录请求错误:', error)
ElMessage({
message: '登录请求出错,请稍后重试!',
type: 'error',
})
})
}

主要使用了axios发了post请求,FastAPI部分是接收json格式,在请求里加了header,这个项目启动的端口是8080,FastAPI的后端端口是4321,涉及到一个跨域问题,又在请求里加了{ withCredentials: true },页面登录部分,代码只修改了这些。

2.路由的修改

router的index.js里加一个dashboard的跳转:

{
path: '/Dashboard',
//name: 'Register',
component: () => import("../views/Dashboard.vue")
},

在view下创建一个Dashboard的空白页面。

<template>
<div class="about">
<h1>This is Dashboard</h1>
</div>
</template>

3.创建数据库

在以前的项目时,已经安装好本地MySQL数据库,为了这个演示,用python只建立一个数据库和表,

import mysql.connector

# 数据库连接配置
db_config = {
'host': 'localhost',
'user': 'root',
'password': '123456'
}

# 初始化 MySQL 连接
def get_db_connection():
return mysql.connector.connect(**db_config)

# 创建数据库和表
def create_database_and_table():
conn = get_db_connection()
cursor = conn.cursor()

# 创建数据库
cursor.execute("CREATE DATABASE IF NOT EXISTS vue_blog")

# 切换到指定数据库
cursor.execute("USE vue_blog")

# 创建用户信息表
cursor.execute("""
CREATE TABLE IF NOT EXISTS user_info (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
nickname VARCHAR(50) NOT NULL,
password VARCHAR(50) NOT NULL
)
""")

cursor.close()
conn.close()


# 查询用户
def query_user(username: str, password: str):
conn = get_db_connection()
cursor = conn.cursor()
# 切换到指定数据库
cursor.execute("USE vue_blog")

# 查询数据库中是否存在该用户
query = "SELECT * FROM user_info WHERE username = %s"
cursor.execute(query, (username,))
user = cursor.fetchone()
print(user)
if user:
# 如果找到了用户,则比对密码
if user[3] == password: # 第4列是密码字段
print("用户名和密码匹配")
else:
print("密码不匹配")
else:
print("用户不存在")

cursor.close()
conn.close()

if __name__ == "__main__":
#create_database_and_table()
query_user("gaofeng", "123456")

连接到本地数据库,创建一个新库和一个表,用于存储用户名信息。

手动填加一个用户信息,用于验证信息,进行登录。

4.编写FastAPI

编写这个后端只提供登录验证,一个Post请求,拿着用户名和密码去验证对比,这里不涉及用户名和密码的加解,都是明文的。

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Optional
import mysql.connector

from fastapi.middleware.cors import CORSMiddleware
# 允许所有来源的跨域请求

# 数据库连接配置
db_config = {
'host': 'localhost',
'user': 'root',
'password': '123456',
'database': 'vue_blog'
}

# 初始化 FastAPI 应用
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:8080"],
allow_credentials=True,
allow_methods=["GET", "POST", "PUT", "DELETE"],
allow_headers=["*"],
)
# 定义请求体模型
class User(BaseModel):
username: str
password: str

# 初始化 MySQL 连接
def get_db_connection():
return mysql.connector.connect(**db_config)

# 根据用户名和密码验证用户
def verify_user(username: str, password: str):
conn = get_db_connection()
cursor = conn.cursor()
cursor.execute("USE vue_blog")
# 查询数据库中是否存在该用户
query = "SELECT * FROM user_info WHERE username = %s AND password = %s"
cursor.execute(query, (username, password))
user = cursor.fetchone()

cursor.close()
conn.close()

return user

# 定义 POST 路由,接收用户名和密码进行验证
@app.post("/login")
def login(user: User):
# 验证用户
print(user)
result = verify_user(user.username, user.password)
print(result)
if result:
return {"message": "Login successful"}
else:
print(result)
raise HTTPException(status_code=401, detail="Unauthorized")

if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=4321)

下面代码是后加的,项目运行端口是8080,后端端口是4321,不做设置会报错,加上下面这些设置,就能正常访问了。

app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:8080"],
allow_credentials=True,
allow_methods=["GET", "POST", "PUT", "DELETE"],
allow_headers=["*"],
)

每次启动项目时,可能端口号会变,端口位置可以设置成*。

5.登录演示

后端运行fastapi这个脚本,前端启动项目,

fastapi关于这个Login的说明。

输入用户名,密码登录,登录成功。

6.登录状态管理

用户登录之后,页面来回切换,需要有个状态管理,就会用到一个Pinia组件。这里主要参考邓瑞编程和吴悠讲编程的pinia内容。这两个视频都是在b站。

安装pinia:

npm install pinia

在package.json中,显示pinia的版本是2.1.7。修改main.js,引入pinia。

import { createPinia } from 'pinia'

const pinia = createPinia()
//createApp(App).use(store).use(router).mount('#app')
const app = createApp(App)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}

app.use(store)
app.use(router)
app.use(ElementPlus)
app.use(pinia)
app.provide('$axios',axios)
app.mount('#app')

在src的store下创建web.js,用于存储用户的登录状态:

import { defineStore } from 'pinia';
import {ref, reactive} from 'vue';
export const useWebStore = defineStore('web',() => {
const user = reactive({
isLoggedIn: false,
userName: null,
})

const login= (userInfo) => {
user.isLoggedIn = true,
user.userInfo = userInfo
console.log(user.userInfo)
}

const logout= () => {
user.isLoggedIn = false,
user.userInfo = null
}
return {
user,
login,
logout
}
})

在Login.vue中修改,引入web.js:

import { useWebStore } from '../store/web'
const userStore = useWebStore()

修改登录成功,跳转前增加登录信息修改:

const Login = reactive({
loginName: '',
password: '',

})

const onSubmit = () => {

const user = {
username: Login.loginName,
password: Login.password
}
console.log(userStore.user.isLoggedIn)
axios.post('http://localhost:4321/login', {
username: Login.loginName,
password: Login.password
},{
headers: {
'Content-Type': 'application/json'
}},
{ withCredentials: true }

)
.then(response => {
console.log(Login)
const { data } = response
if (data.message === 'Login successful') {
//router.push('/dashboard')
ElMessage({
message: '恭喜,登录成功!',
type: 'success',
})
userStore.login(Login.loginName)
console.log(userStore.user.isLoggedIn)
router.push('/dashboard')
} else {
ElMessage({
message: '登录失败,请检查用户名和密码!',
type: 'error',
})
}
})
.catch(error => {
console.error('登录请求错误:', error)
ElMessage({
message: '登录请求出错,请稍后重试!',
type: 'error',
})
})
}

登录前后打印登录状态。

7.登录状态持久化

安装pinia的持久化插件,把pinia的存储到本地localStorage中:

npm i pinia-plugin-persistedstate

在main.js中导入,并在pinia中使用。

//从 pinia-plugin-persistedstate 模块中导入 piniaPluginPersistedstate
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'


const pinia = createPinia()
//将插件添加到 pinia 实例上
pinia.use(piniaPluginPersistedstate)

在上面的web.js中填加一个参数,填加一个{persist:true}:

import { defineStore } from 'pinia';
import {ref, reactive} from 'vue';
export const useWebStore = defineStore('web',() => {
const user = reactive({
isLoggedIn: false,
userName: null,
})

const login= (userInfo) => {
user.isLoggedIn = true,
user.userInfo = userInfo
console.log(user.userInfo)
}

const logout= () => {
user.isLoggedIn = false,
user.userInfo = null
}
return {
user,
login,
logout
}
},
{ persist:true
})

再次登录成功后,在控制台,应用程序的LocaStorage中,可以看到

再次登录时,登录前和登录后,

说明他的登录状态是保持的,有了这个插件,他会自动读取信息,无需手动操作。

8.文件下载

上面项目代码都比较简单,如果需要,后台回复『0415』获取所有代码和资源。

本文章转载微信公众号@峰哥Python笔记

#你可能也喜欢这些API文章!