代码地址:https://github.com/wendingming/fastapi-vue-postgresql
昨天我用VUE完善了登录页面,并访问登录接口,获得了token返回值。
今天我们来学习一下,VUE前端,利用store来建立【保存token,判断token有没有过期,过期则弹出提示,跳转到重新登录页面,】这些方法。
唉,学来学去,尼玛的,VUE事情最多。。。
果然,前端都是神,后端一个接口,前端薅成秃头。
首先:改axios调用接口的方法,也就是前面写的http.js。
在其中响应拦截时,判断是否有token过期提示代码,【这个需要和后端约定好,用某个代码代表超时】
还是说一段fastapi代码吧,不然真的都变成VUE学习了。。。
后端fastapi的login.py文件,在我之前有从官方文档复制出来,现在详细解析了一下【主要是加了中文注释说明】,代码如下:
# 导入相关的模块
from datetime import datetime, timedelta
from typing import Optional
from fastapi import Depends, FastAPI, HTTPException, status, Form
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from jose import JWTError, jwt
from passlib.context import CryptContext
from pydantic import BaseModel
from starlette.middleware.cors import CORSMiddleware
import json
"""定义关于token的相关常量
SECRET_KEY : 用于加密解密的密钥,只允许服务器知道,打死不告诉别人
可以执行 openssl rand -hex 32 获取一串随机的字符
ALGORITHM : 定义加密解密所使用的算法
ACCESS_TOKEN_EXPIRE_MINUTES : token的有效期
"""
SECRET_KEY = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
dict_permisson = [
{
"menu_id":1,
"menu_name":"系统首页",
"parent_id":0,
"pageurl":"/sys/index"
},
{
"menu_id":2,
"menu_name":"菜单管理",
"parent_id":1,
"pageurl":"/sys/list"
},
{
"menu_id":3,
"menu_name":"角色管理",
"parent_id":1,
"pageurl":"/sys/role"
},
{
"menu_id":4,
"menu_name":"管理员管理",
"parent_id":1,
"pageurl":"/sys/admin"
},
{
"menu_id":5,
"menu_name":"用户管理",
"parent_id":0,
"pageurl":"/user/index"
},
{
"menu_id":6,
"menu_name":"会员列表",
"parent_id":5,
"pageurl":"/user/list"
},
]
json_permisson = json.dumps(dict_permisson)
# 这里定义一个字典,来模拟数据库中的数据
fake_users_db = {
"johndoe": {
"uid": 1,
"username": "johndoe",
"full_name": "John Doe",
"avatar": "https://up.enterdesk.com/2021/edpic/c4/9f/09/c49f090757360f843141fe2bab2cfc8f_1.jpg",
"email": "johndoe@example.com",
"hashed_password": "$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW",#默认密码secret
"disabled": False,
"permisson": json_permisson
}
}
class Token(BaseModel):
"""定义token的数据模型"""
access_token: str
token_type: str
class TokenData(BaseModel):
username: Optional[str] = None
class FormData(BaseModel):
uname: str
passwd: str
class User(BaseModel):
"""定义用户的数据模型"""
uid: str
username: str
full_name: Optional[str] = None
avatar: Optional[str] = None
email: Optional[str] = None
disabled: Optional[bool] = None
permisson: Optional[str] = None
class UserInDB(User):
hashed_password: str
# 创建一个加密解密上下文环境(甚至可以不用管这两句话啥意思)
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# 实例化一个FastAPI实例
app = FastAPI()
# 设置允许访问的域名
origins = [
"http://localhost",
"http://localhost:8080",
"http://127.0.0.1",
"*"
] #也可以设置为"*",即为所有。
# 设置跨域传参
app.add_middleware(
CORSMiddleware,
allow_origins=origins, # 设置允许的origins来源
allow_credentials=True,
allow_methods=["*"], # 设置允许跨域的http方法,比如 get、post、put等。
allow_headers=["*"]) # 允许跨域的headers,可以用来鉴别来源等作用。
def verify_password(plain_password, hashed_password):
"""验证密码是否正确
:param plain_password: 明文
:param hashed_password: 明文hash值
:return:
"""
return pwd_context.verify(plain_password, hashed_password)
def get_password_hash(password):
"""获取密码的hash值
:param password: 欲获取hash的明文密码
:return: 返回一个hash字符串
"""
return pwd_context.hash(password)
def get_user(db, username: str):
"""查询用户
:param