feat: api visit auth
This commit is contained in:
parent
fc1acab2d5
commit
9ce271d691
@ -4,15 +4,10 @@ from fastapi import Query
|
|||||||
|
|
||||||
from core.utils import list_to_tree
|
from core.utils import list_to_tree
|
||||||
from dbhelper.relation import role_assigned_menu
|
from dbhelper.relation import role_assigned_menu
|
||||||
from dbhelper.role import (
|
from dbhelper.role import (del_role, get_role, get_role_menus, get_roles,
|
||||||
del_role,
|
new_role, put_role)
|
||||||
get_role,
|
from schemas import (ListAll, Response, RoleIn, RoleInfo, RoleMenuIn,
|
||||||
get_role_menus,
|
RoleQuery, RoleRead)
|
||||||
get_roles,
|
|
||||||
new_role,
|
|
||||||
put_role,
|
|
||||||
)
|
|
||||||
from schemas import ListAll, Response, RoleIn, RoleInfo, RoleMenuIn, RoleQuery, RoleRead
|
|
||||||
|
|
||||||
|
|
||||||
async def role_add(data: RoleIn) -> Response[RoleInfo]:
|
async def role_add(data: RoleIn) -> Response[RoleInfo]:
|
||||||
|
@ -1,14 +1,8 @@
|
|||||||
from fastapi import Query
|
from fastapi import Query
|
||||||
|
|
||||||
from core.security import get_password_hash
|
from core.security import get_password_hash
|
||||||
from dbhelper.user import (
|
from dbhelper.user import (del_user, get_user, get_user_info, get_users,
|
||||||
del_user,
|
insert_user, put_user)
|
||||||
get_user,
|
|
||||||
get_user_info,
|
|
||||||
get_users,
|
|
||||||
insert_user,
|
|
||||||
put_user,
|
|
||||||
)
|
|
||||||
from schemas import Response, UserAdd, UserInfo, UserPut, UserQuery, UserRead
|
from schemas import Response, UserAdd, UserInfo, UserPut, UserQuery, UserRead
|
||||||
from schemas.common import ListAll
|
from schemas.common import ListAll
|
||||||
|
|
||||||
|
@ -1,6 +1,23 @@
|
|||||||
from fastapi.exceptions import HTTPException
|
from fastapi.exceptions import HTTPException
|
||||||
|
from starlette.requests import Request
|
||||||
|
from starlette.responses import JSONResponse
|
||||||
|
|
||||||
|
|
||||||
class TokenAuthFailure(HTTPException):
|
class TokenAuthFailure(HTTPException):
|
||||||
status_code = 401
|
|
||||||
detail = "认证失败"
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class PermissionsError(HTTPException):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
async def http_exception(request: Request, exc: HTTPException):
|
||||||
|
return JSONResponse(
|
||||||
|
{"msg": exc.detail, "code": exc.status_code, "data": None},
|
||||||
|
status_code=exc.status_code,
|
||||||
|
headers=exc.headers,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
exception_handlers = {HTTPException: http_exception}
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from fastapi import Depends
|
from fastapi import Depends, Request
|
||||||
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
||||||
from jose import JWTError, jwt
|
from jose import JWTError, jwt
|
||||||
from passlib.context import CryptContext
|
from passlib.context import CryptContext
|
||||||
|
|
||||||
from core.exceptions import TokenAuthFailure
|
from core.exceptions import PermissionsError, TokenAuthFailure
|
||||||
from dbhelper.user import get_user
|
from dbhelper.menu import get_apis, get_has_api
|
||||||
|
from dbhelper.user import get_user, get_user_info
|
||||||
|
from models import UserModel
|
||||||
|
|
||||||
# JWT
|
# JWT
|
||||||
SECRET_KEY = "lLNiBWPGiEmCLLR9kRGidgLY7Ac1rpSWwfGzTJpTmCU"
|
SECRET_KEY = "lLNiBWPGiEmCLLR9kRGidgLY7Ac1rpSWwfGzTJpTmCU"
|
||||||
@ -59,4 +61,33 @@ async def check_token(security: HTTPAuthorizationCredentials = Depends(bearer)):
|
|||||||
username: str = payload.get("sub")
|
username: str = payload.get("sub")
|
||||||
return await get_user({"username": username})
|
return await get_user({"username": username})
|
||||||
except JWTError:
|
except JWTError:
|
||||||
raise TokenAuthFailure
|
raise TokenAuthFailure(403, "认证失败")
|
||||||
|
|
||||||
|
|
||||||
|
async def check_permissions(request: Request, user: UserModel = Depends(check_token)):
|
||||||
|
"""检查接口权限"""
|
||||||
|
# 查询当前激活角色
|
||||||
|
result = await get_user_info(user)
|
||||||
|
active_rid = result["roles"][0]["id"]
|
||||||
|
|
||||||
|
# 白名单
|
||||||
|
whitelist = [f"/user/{user.id}", f"/role/{active_rid}/menu"]
|
||||||
|
flag = request.url.path in whitelist and request.method == "GET"
|
||||||
|
if flag:
|
||||||
|
return
|
||||||
|
|
||||||
|
api = request.url.path
|
||||||
|
for k, v in request.path_params.items():
|
||||||
|
api = api.replace(v, "{%s}" % k)
|
||||||
|
# 方法1. 每一次去查数据库
|
||||||
|
# result = await get_has_api(active_rid, api, request.method)
|
||||||
|
|
||||||
|
# 2. 登录之后查一次 后面去结果查 todo 更新权限时需要更新 , 最好结果放redis
|
||||||
|
cache_key = f"{user.username}_{active_rid}"
|
||||||
|
# 缓存到fastapi 应用实例中
|
||||||
|
if not hasattr(request.app.state, cache_key):
|
||||||
|
setattr(request.app.state, cache_key, await get_apis(active_rid))
|
||||||
|
if {"api": api, "method": request.method} not in getattr(
|
||||||
|
request.app.state, cache_key
|
||||||
|
):
|
||||||
|
raise PermissionsError(403, detail="无权访问")
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
from tortoise import connections
|
||||||
|
|
||||||
from models import MenuModel
|
from models import MenuModel
|
||||||
from schemas.menu import MenuIn
|
from schemas.menu import MenuIn
|
||||||
|
|
||||||
@ -41,3 +43,27 @@ async def get_menu(kwargs):
|
|||||||
async def del_menu(mid: int):
|
async def del_menu(mid: int):
|
||||||
"""删除用户"""
|
"""删除用户"""
|
||||||
return await MenuModel.filter(id=mid).update(status=9)
|
return await MenuModel.filter(id=mid).update(status=9)
|
||||||
|
|
||||||
|
|
||||||
|
async def get_has_api(pk: int, api: str, method: str):
|
||||||
|
"""获取角色接口权限 每次来查数据库"""
|
||||||
|
db = connections.get("default")
|
||||||
|
return await db.execute_query_dict(
|
||||||
|
"""
|
||||||
|
select m.api, m.method
|
||||||
|
FROM sys_menu as m, sys_role_menu as srm WHERE m.id = srm.mid
|
||||||
|
AND srm.rid = (?) and m.api = (?) and m.method = (?) and m.status != 9""",
|
||||||
|
[pk, api, method],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def get_apis(pk: int):
|
||||||
|
"""返回当前角色拥有的接口权限列表"""
|
||||||
|
db = connections.get("default")
|
||||||
|
return await db.execute_query_dict(
|
||||||
|
"""
|
||||||
|
select m.api, m.method
|
||||||
|
FROM sys_menu as m, sys_role_menu as srm WHERE m.id = srm.mid
|
||||||
|
AND srm.rid = (?) and m.status != 9""",
|
||||||
|
[pk],
|
||||||
|
)
|
||||||
|
@ -11,7 +11,7 @@ async def get_role_menus(rid: int):
|
|||||||
db = connections.get("default")
|
db = connections.get("default")
|
||||||
return await db.execute_query_dict(
|
return await db.execute_query_dict(
|
||||||
"""
|
"""
|
||||||
select m.id, m.name, m.meta, m.path, m.type, m.component, m.pid, m.identifier, m.regx,m.api, m.method
|
select m.id, m.name, m.meta, m.path, m.type, m.component, m.pid, m.identifier
|
||||||
FROM sys_menu as m, sys_role_menu WHERE m.id = sys_role_menu.mid
|
FROM sys_menu as m, sys_role_menu WHERE m.id = sys_role_menu.mid
|
||||||
AND sys_role_menu.rid = (?) AND m.`status` = 1""",
|
AND sys_role_menu.rid = (?) AND m.`status` = 1""",
|
||||||
[rid],
|
[rid],
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
|
|
||||||
from core.events import close_orm, init_orm
|
from core.events import close_orm, init_orm
|
||||||
|
from core.exceptions import exception_handlers
|
||||||
from core.log import logger
|
from core.log import logger
|
||||||
from core.middleware import middlewares
|
from core.middleware import middlewares
|
||||||
from router.url import routes
|
from router.url import routes
|
||||||
@ -10,14 +11,13 @@ app = FastAPI(
|
|||||||
on_shutdown=[close_orm],
|
on_shutdown=[close_orm],
|
||||||
routes=routes,
|
routes=routes,
|
||||||
middleware=middlewares,
|
middleware=middlewares,
|
||||||
|
exception_handlers=exception_handlers,
|
||||||
)
|
)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import uvicorn
|
import uvicorn
|
||||||
|
|
||||||
for i in app.routes:
|
for i in app.routes:
|
||||||
logger.info(
|
logger.info(f"{i.path}, {i.methods}, {i.__dict__.get('summary')}, {i.endpoint}")
|
||||||
f"{i.path}, {i.methods}, {i.path_regex}, {i.__dict__.get('summary')}, {i.endpoint}"
|
|
||||||
)
|
|
||||||
|
|
||||||
uvicorn.run("main:app", reload=True)
|
uvicorn.run("main:app", reload=True)
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -15,7 +15,6 @@ class MenuModel(Table):
|
|||||||
identifier = fields.CharField(max_length=30, description="权限标识 user:add", null=True)
|
identifier = fields.CharField(max_length=30, description="权限标识 user:add", null=True)
|
||||||
api = fields.CharField(max_length=128, description="接口地址", null=True)
|
api = fields.CharField(max_length=128, description="接口地址", null=True)
|
||||||
method = fields.CharField(max_length=10, description="接口请求方式", null=True)
|
method = fields.CharField(max_length=10, description="接口请求方式", null=True)
|
||||||
regx = fields.CharField(max_length=50, description="接口地址正则表达式", null=True)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
table = "sys_menu"
|
table = "sys_menu"
|
||||||
|
@ -4,17 +4,11 @@ from fastapi import Depends, routing
|
|||||||
|
|
||||||
from controller.common import about, login
|
from controller.common import about, login
|
||||||
from controller.menu import menu_add, menu_arr, menu_del
|
from controller.menu import menu_add, menu_arr, menu_del
|
||||||
from controller.role import (
|
from controller.role import (assigned_menu, role_add, role_arr, role_del,
|
||||||
assigned_menu,
|
role_has_menu, role_put, role_query)
|
||||||
role_add,
|
from controller.user import (user_add, user_arr, user_del, user_info,
|
||||||
role_arr,
|
user_list, user_put)
|
||||||
role_del,
|
from core.security import check_permissions
|
||||||
role_has_menu,
|
|
||||||
role_put,
|
|
||||||
role_query,
|
|
||||||
)
|
|
||||||
from controller.user import user_add, user_arr, user_del, user_info, user_list, user_put
|
|
||||||
from core.security import check_token
|
|
||||||
|
|
||||||
|
|
||||||
class Route(routing.APIRoute):
|
class Route(routing.APIRoute):
|
||||||
@ -113,48 +107,55 @@ class Route(routing.APIRoute):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
has_perm = {"dependencies": [Depends(check_permissions)]}
|
||||||
|
|
||||||
routes = [
|
routes = [
|
||||||
Route.post("/login", endpoint=login, tags=["公共"], summary="登录"),
|
Route.post("/login", endpoint=login, tags=["公共"], summary="登录"),
|
||||||
Route.get("/about", endpoint=about, tags=["公共"], summary="关于"),
|
Route.get("/about", endpoint=about, tags=["公共"], summary="关于", **has_perm),
|
||||||
# 用户管理
|
# 用户管理
|
||||||
Route.get("/user", endpoint=user_arr, tags=["用户管理"], summary="用户列表"),
|
Route.get("/user", endpoint=user_arr, tags=["用户管理"], summary="用户列表", **has_perm),
|
||||||
Route.post("/user", endpoint=user_add, tags=["用户管理"], summary="用户新增"),
|
Route.post("/user", endpoint=user_add, tags=["用户管理"], summary="用户新增", **has_perm),
|
||||||
Route.delete(
|
Route.delete(
|
||||||
"/user/{pk}",
|
"/user/{pk}", endpoint=user_del, tags=["用户管理"], summary="用户删除", **has_perm
|
||||||
endpoint=user_del,
|
|
||||||
tags=["用户管理"],
|
|
||||||
summary="用户删除",
|
|
||||||
),
|
),
|
||||||
Route.put("/user/{pk}", endpoint=user_put, tags=["用户管理"], summary="用户更新"),
|
Route.put(
|
||||||
Route.get("/user/{pk}", endpoint=user_info, tags=["用户管理"], summary="用户信息"),
|
"/user/{pk}", endpoint=user_put, tags=["用户管理"], summary="用户更新", **has_perm
|
||||||
Route.post("/user/query", endpoint=user_list, tags=["用户管理"], summary="用户列表查询"),
|
|
||||||
# 角色管理,
|
|
||||||
Route.get("/role", endpoint=role_arr, tags=["角色管理"], summary="角色列表"),
|
|
||||||
Route.post("/role", endpoint=role_add, tags=["角色管理"], summary="角色新增"),
|
|
||||||
Route.delete(
|
|
||||||
"/role/{pk}",
|
|
||||||
endpoint=role_del,
|
|
||||||
tags=["角色管理"],
|
|
||||||
summary="角色删除",
|
|
||||||
dependencies=[Depends(check_token)],
|
|
||||||
),
|
),
|
||||||
Route.get(
|
Route.get(
|
||||||
"/role/{rid}/menu", endpoint=role_has_menu, tags=["角色管理"], summary="查询角色拥有权限"
|
"/user/{pk}", endpoint=user_info, tags=["用户管理"], summary="用户信息", **has_perm
|
||||||
),
|
),
|
||||||
Route.put("/role", endpoint=role_put, tags=["角色管理"], summary="角色更新"),
|
|
||||||
Route.post("/role/query", endpoint=role_query, tags=["角色管理"], summary="角色条件查询"),
|
|
||||||
Route.post(
|
Route.post(
|
||||||
"/role/assigned/menu", endpoint=assigned_menu, tags=["角色管理"], summary="角色分配菜单"
|
"/user/query", endpoint=user_list, tags=["用户管理"], summary="用户列表查询", **has_perm
|
||||||
|
),
|
||||||
|
# 角色管理,
|
||||||
|
Route.get("/role", endpoint=role_arr, tags=["角色管理"], summary="角色列表", **has_perm),
|
||||||
|
Route.post("/role", endpoint=role_add, tags=["角色管理"], summary="角色新增", **has_perm),
|
||||||
|
Route.delete(
|
||||||
|
"/role/{pk}", endpoint=role_del, tags=["角色管理"], summary="角色删除", **has_perm
|
||||||
|
),
|
||||||
|
Route.get(
|
||||||
|
"/role/{rid}/menu",
|
||||||
|
endpoint=role_has_menu,
|
||||||
|
tags=["角色管理"],
|
||||||
|
summary="查询角色拥有权限",
|
||||||
|
**has_perm
|
||||||
|
),
|
||||||
|
Route.put("/role", endpoint=role_put, tags=["角色管理"], summary="角色更新", **has_perm),
|
||||||
|
Route.post(
|
||||||
|
"/role/query", endpoint=role_query, tags=["角色管理"], summary="角色条件查询", **has_perm
|
||||||
|
),
|
||||||
|
Route.post(
|
||||||
|
"/role/assigned/menu",
|
||||||
|
endpoint=assigned_menu,
|
||||||
|
tags=["角色管理"],
|
||||||
|
summary="角色分配菜单",
|
||||||
|
**has_perm
|
||||||
),
|
),
|
||||||
# 菜单新增
|
# 菜单新增
|
||||||
Route.get("/menu", endpoint=menu_arr, tags=["菜单管理"], summary="菜单列表"),
|
Route.get("/menu", endpoint=menu_arr, tags=["菜单管理"], summary="菜单列表", **has_perm),
|
||||||
Route.post("/menu", endpoint=menu_add, tags=["菜单管理"], summary="菜单新增"),
|
Route.post("/menu", endpoint=menu_add, tags=["菜单管理"], summary="菜单新增", **has_perm),
|
||||||
Route.delete(
|
Route.delete(
|
||||||
"/menu/{pk}",
|
"/menu/{pk}", endpoint=menu_del, tags=["菜单管理"], summary="菜单删除", **has_perm
|
||||||
endpoint=menu_del,
|
|
||||||
tags=["菜单管理"],
|
|
||||||
summary="菜单删除",
|
|
||||||
dependencies=[Depends(check_token)],
|
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@ class MenuBasic(BaseModel):
|
|||||||
identifier: Optional[str] = Field(default=None, description="权限标识符 -> 按钮显示")
|
identifier: Optional[str] = Field(default=None, description="权限标识符 -> 按钮显示")
|
||||||
api: Optional[str] = Field(default=None, description="后端接口地址")
|
api: Optional[str] = Field(default=None, description="后端接口地址")
|
||||||
method: Optional[str] = Field(default=None, description="接口请求方法")
|
method: Optional[str] = Field(default=None, description="接口请求方法")
|
||||||
regx: Optional[str] = Field(default=None, description="正则匹配")
|
|
||||||
|
|
||||||
|
|
||||||
class MenuIn(MenuBasic):
|
class MenuIn(MenuBasic):
|
||||||
|
@ -51,7 +51,6 @@ params = [
|
|||||||
identifier=None,
|
identifier=None,
|
||||||
api=None,
|
api=None,
|
||||||
method=None,
|
method=None,
|
||||||
regx=None,
|
|
||||||
).dict(),
|
).dict(),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -66,7 +65,6 @@ params = [
|
|||||||
identifier=None,
|
identifier=None,
|
||||||
api=None,
|
api=None,
|
||||||
method=None,
|
method=None,
|
||||||
regx=None,
|
|
||||||
).dict(),
|
).dict(),
|
||||||
),
|
),
|
||||||
# 组件
|
# 组件
|
||||||
@ -81,8 +79,7 @@ params = [
|
|||||||
pid=1,
|
pid=1,
|
||||||
identifier=None,
|
identifier=None,
|
||||||
api="/user",
|
api="/user",
|
||||||
method="{'GET'}",
|
method="GET",
|
||||||
regx="^/user$",
|
|
||||||
).dict(),
|
).dict(),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -96,8 +93,7 @@ params = [
|
|||||||
pid=1,
|
pid=1,
|
||||||
identifier=None,
|
identifier=None,
|
||||||
api="/role",
|
api="/role",
|
||||||
method="{'GET'}",
|
method="GET",
|
||||||
regx="^/role$",
|
|
||||||
).dict(),
|
).dict(),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -111,8 +107,7 @@ params = [
|
|||||||
pid=1,
|
pid=1,
|
||||||
identifier=None,
|
identifier=None,
|
||||||
api="/menu",
|
api="/menu",
|
||||||
method="{'GET'}",
|
method="GET",
|
||||||
regx="^/menu$",
|
|
||||||
).dict(),
|
).dict(),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -126,8 +121,7 @@ params = [
|
|||||||
pid=2,
|
pid=2,
|
||||||
identifier=None,
|
identifier=None,
|
||||||
api="/about",
|
api="/about",
|
||||||
method="{'GET'}",
|
method="GET",
|
||||||
regx="^/about",
|
|
||||||
).dict(),
|
).dict(),
|
||||||
),
|
),
|
||||||
# 按钮
|
# 按钮
|
||||||
@ -142,8 +136,7 @@ params = [
|
|||||||
pid=3,
|
pid=3,
|
||||||
identifier="user:create",
|
identifier="user:create",
|
||||||
api="/user",
|
api="/user",
|
||||||
method="{'POST'}",
|
method="POST",
|
||||||
regx="^/user$",
|
|
||||||
).dict(),
|
).dict(),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -157,8 +150,7 @@ params = [
|
|||||||
pid=3,
|
pid=3,
|
||||||
identifier="user:delete",
|
identifier="user:delete",
|
||||||
api="/user/{pk}",
|
api="/user/{pk}",
|
||||||
method="{'DELETE'}",
|
method="DELETE",
|
||||||
regx="^/user/(?P<pk>[^/]+)$",
|
|
||||||
).dict(),
|
).dict(),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -172,8 +164,7 @@ params = [
|
|||||||
pid=3,
|
pid=3,
|
||||||
identifier="user:update",
|
identifier="user:update",
|
||||||
api="/user/{pk}",
|
api="/user/{pk}",
|
||||||
method="{'PUT'}",
|
method="PUT",
|
||||||
regx="^/user/(?P<pk>[^/]+)$",
|
|
||||||
).dict(),
|
).dict(),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -187,8 +178,7 @@ params = [
|
|||||||
pid=3,
|
pid=3,
|
||||||
identifier="user:get",
|
identifier="user:get",
|
||||||
api="/user/{pk}",
|
api="/user/{pk}",
|
||||||
method="{'GET'}",
|
method="GET",
|
||||||
regx="^/user/(?P<pk>[^/]+)$",
|
|
||||||
).dict(),
|
).dict(),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -202,8 +192,7 @@ params = [
|
|||||||
pid=3,
|
pid=3,
|
||||||
identifier="user:query",
|
identifier="user:query",
|
||||||
api="/user/query",
|
api="/user/query",
|
||||||
method="{'POST'}",
|
method="POST",
|
||||||
regx="^/user/query$",
|
|
||||||
).dict(),
|
).dict(),
|
||||||
),
|
),
|
||||||
# 角色管理
|
# 角色管理
|
||||||
@ -218,8 +207,7 @@ params = [
|
|||||||
pid=4,
|
pid=4,
|
||||||
identifier="role:create",
|
identifier="role:create",
|
||||||
api="/role",
|
api="/role",
|
||||||
method="{'POST'}",
|
method="POST",
|
||||||
regx="^/role$",
|
|
||||||
).dict(),
|
).dict(),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -233,8 +221,7 @@ params = [
|
|||||||
pid=4,
|
pid=4,
|
||||||
identifier="role:delete",
|
identifier="role:delete",
|
||||||
api="/role/{pk}",
|
api="/role/{pk}",
|
||||||
method="{'DELETE'}",
|
method="DELETE",
|
||||||
regx="^/role/(?P<pk>[^/]+)$",
|
|
||||||
).dict(),
|
).dict(),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -248,8 +235,7 @@ params = [
|
|||||||
pid=4,
|
pid=4,
|
||||||
identifier=None,
|
identifier=None,
|
||||||
api="/role/{rid}/menu",
|
api="/role/{rid}/menu",
|
||||||
method="{'GET'}",
|
method="GET",
|
||||||
regx="^/role/(?P<rid>[^/]+)/menu$",
|
|
||||||
).dict(),
|
).dict(),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -263,8 +249,7 @@ params = [
|
|||||||
pid=4,
|
pid=4,
|
||||||
identifier="",
|
identifier="",
|
||||||
api="/role/query",
|
api="/role/query",
|
||||||
method="{'POST'}",
|
method="POST",
|
||||||
regx="^/role/query$",
|
|
||||||
).dict(),
|
).dict(),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -278,8 +263,7 @@ params = [
|
|||||||
pid=4,
|
pid=4,
|
||||||
identifier="role:assign",
|
identifier="role:assign",
|
||||||
api="/role/assigned/menu",
|
api="/role/assigned/menu",
|
||||||
method="{'POST'}",
|
method="POST",
|
||||||
regx="^/role/assigned/menu$",
|
|
||||||
).dict(),
|
).dict(),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -293,8 +277,7 @@ params = [
|
|||||||
pid=4,
|
pid=4,
|
||||||
identifier="role:update",
|
identifier="role:update",
|
||||||
api="/role",
|
api="/role",
|
||||||
method="{'PUT'}",
|
method="PUT",
|
||||||
regx="^/role$",
|
|
||||||
).dict(),
|
).dict(),
|
||||||
),
|
),
|
||||||
# 菜单管理的权限
|
# 菜单管理的权限
|
||||||
@ -309,8 +292,7 @@ params = [
|
|||||||
pid=5,
|
pid=5,
|
||||||
identifier="menu:create",
|
identifier="menu:create",
|
||||||
api="/menu",
|
api="/menu",
|
||||||
method="{'POST'}",
|
method="POST",
|
||||||
regx="^/menu$",
|
|
||||||
).dict(),
|
).dict(),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -324,8 +306,7 @@ params = [
|
|||||||
pid=5,
|
pid=5,
|
||||||
identifier="menu:delete",
|
identifier="menu:delete",
|
||||||
api="/menu/{pk}",
|
api="/menu/{pk}",
|
||||||
method="{'DELETE'}",
|
method="DELETE",
|
||||||
regx="/menu/(?P<pk>[^/]+)$",
|
|
||||||
).dict(),
|
).dict(),
|
||||||
),
|
),
|
||||||
# 分配权限
|
# 分配权限
|
||||||
@ -333,7 +314,7 @@ params = [
|
|||||||
"/role/assigned/menu",
|
"/role/assigned/menu",
|
||||||
RoleMenuIn(rid=1, menus=[num for num in range(1, 20)]).dict(),
|
RoleMenuIn(rid=1, menus=[num for num in range(1, 20)]).dict(),
|
||||||
),
|
),
|
||||||
("/role/assigned/menu", RoleMenuIn(rid=2, menus=[3, 7, 8, 9, 10, 11]).dict()),
|
("/role/assigned/menu", RoleMenuIn(rid=2, menus=[1, 3, 7, 8, 9, 11]).dict()),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,6 +12,14 @@ export const userStore = defineStore('user', () => {
|
|||||||
// getter
|
// getter
|
||||||
const accessToken = computed(() => 'Bearer ' + token.value)
|
const accessToken = computed(() => 'Bearer ' + token.value)
|
||||||
|
|
||||||
|
// setup store 不提供$reset 需要自己重置
|
||||||
|
// https://github.com/vuejs/pinia/issues/1056
|
||||||
|
const $reset = () => {
|
||||||
|
token.value = ""
|
||||||
|
userInfo.value = {}
|
||||||
|
userMenus.value = []
|
||||||
|
}
|
||||||
|
|
||||||
// 非setup语法时的actions
|
// 非setup语法时的actions
|
||||||
const loginAction = async (data) => {
|
const loginAction = async (data) => {
|
||||||
|
|
||||||
@ -34,7 +42,8 @@ export const userStore = defineStore('user', () => {
|
|||||||
ElMessage.success("登录成功.")
|
ElMessage.success("登录成功.")
|
||||||
}
|
}
|
||||||
|
|
||||||
return { token, accessToken, userInfo, userMenus, loginAction }
|
return { token, accessToken, userInfo, userMenus,
|
||||||
|
$reset, loginAction }
|
||||||
}, {
|
}, {
|
||||||
persist: true, // 解决pinia刷新时数据丢失问题
|
persist: true, // 解决pinia刷新时数据丢失问题
|
||||||
})
|
})
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
|
import router from '@/router';
|
||||||
|
import { userStore } from '@/stores/user';
|
||||||
|
const store = userStore()
|
||||||
|
|
||||||
|
const logout = () => {
|
||||||
|
store.$reset()
|
||||||
|
router.push('/login')
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -7,7 +14,9 @@
|
|||||||
<el-container>
|
<el-container>
|
||||||
<el-aside width="200px">Aside</el-aside>
|
<el-aside width="200px">Aside</el-aside>
|
||||||
<el-container>
|
<el-container>
|
||||||
<el-header>Header</el-header>
|
<el-header>Header <el-button @click="logout">
|
||||||
|
注销
|
||||||
|
</el-button></el-header>
|
||||||
<el-main>Main</el-main>
|
<el-main>Main</el-main>
|
||||||
<el-footer>Footer</el-footer>
|
<el-footer>Footer</el-footer>
|
||||||
</el-container>
|
</el-container>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user