3 Star 16 Fork 6

星星在线 / FastAPI-MySQL-Tortoise-Casbin

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

更新记录

2021-08-08

  1. 使用 asynccabin 库操作 casbin 权限处理模块 注意这个库的源文件与casbin库的源文件目录相同,因此在安装的时候会出现覆盖的情况,如果安装完后有异常,可以使用pip uninstall asynccasbin卸载这个库,然后重新安装即可
  2. 修复权限处理模块异常
  3. 增加了 OpenAPI 的统一认证功能,为了适配此功能,登录模块的返回值未采用统一的返回格式

2021-07-25

  1. 使用.env配置不同环境
  2. 增加 Casbin 权限配置接口,具体文档:Casbin使用

注意: WebSocket 不支持 Session 共享,所以如果在项目使用了 WebSocket 功能,则不能使用多进程或者分布式部署,WebSocket 的分布式部署需要借助其他的服务

2021-07-04

  1. 增加 settings.py 配置文件,将通用配置写入,开发/发布环境各自单独配置
  2. 修复权限验证 BUG
  3. 增加 WebSocket 功能
  4. 增加多数据库配置功能
  5. 增加通用请求返回模板 ResultResponse

FastAPI+MySQL+Tortoise-orm项目模板

简介

使用FastAPI + MySql + Tortoise-orm 作为主要数据库操作,项目结构参考:

功能

  • JWT token 认证。
  • 使用 Tortoise-orm models(MySQL).
  • 基于 casbin 的权限验证
  • loguru 日志模块使用
  • 增加 WebSocket 功能

项目文件组织

权限控制

  • 登录、注册及路由中含有openapi的接口不进行登录和权限认证
# 重载了 FastAPI.OAuth2 模块进行登录认证,此模块可以在 API 文档界面进行统一登录认证
# 为了适配这个功能登录接口的返回数据未采用统一格式,使用的时候需要注意
class OAuth2CustomJwt(OAuth2):
    ......
    async def __call__(self, request: Request) -> Optional[str]:
        """
        除了开放API、登录、注册、WebSocket接口外,其他接口均需要登录验证
        """
        for url, op in settings.NO_VERIFY_URL.items():
            if op == 'eq' and url == request.url.path.lower():
                return None
            elif op == 'in' and url in request.url.path.lower():
                return None

        authorization: str = request.headers.get("Authorization")
        scheme, param = get_authorization_scheme_param(authorization)
        if not authorization or scheme.lower() != "bearer":
            if self.auto_error:
                raise HTTPException(
                    status_code=status.HTTP_403_FORBIDDEN, detail="Not authenticated"
                )
            else:
                return None

        try:
            playload = jwt.decode(
                param,
                settings.SECRET_KEY, algorithms=[settings.ALGORITHM]
            )
        except jwt.ExpiredSignatureError:
            raise custom_exc.TokenExpired()
        except (jwt.JWTError, ValidationError, AttributeError):
            raise custom_exc.TokenAuthError()

        username = playload.get('username')
        user = await get_user_by_name(username=username)
        if not user:
            raise AuthenticationError("认证失败")

        """在 Request 对象中设置用户对象,这样在其他地方就能通过 request.state.user 获取到当前用户了"""
        request.state.user = user
  • 全局登录认证(除以上接口外,其余接口均进行登录认证)

登录认证成功后, request.state 会添加一个 user 属性,在所有地方可以通过 request.state.user 获取当前用户信息

app = FastAPI(
        debug=settings.DEBUG,
        title=settings.TITLE,
        description=settings.DESCRIPTION,
        docs_url=settings.DOCS_URL,
        redoc_url=settings.REDOC_URL,
        dependencies=[Depends(OAuth2CustomJwt(tokenUrl="/user/login"))]
    )

全局进行 Depends(OAuth2CustomJwt(tokenUrl="/user/login")) 依赖注入

  • 接口权限认证

首先通过以下接口进行权限配置

在接口上添加 Depends(Authority('user,check')) 依赖注入来判断权限

@router.get(
    "/info",
    summary="获取当前用户信息",
    name="获取当前用户信息",
    response_model=schema.UserOut,
    response_model_exclude_unset=True,
    dependencies=[Depends(Authority('user,check'))]
)
  • 操作权限认证

在接口中进行特殊权限认证,只要使用check_authority函数判断即可,如果无权限会抛出异常

await check_authority(f'{request.state.user.username},auth,add')

配置

在 settings.py 中是进行项目配置,config/.env 文件中通过环境变量进行发布环境配置

  • 修改 API 文档默认地址

为了通过权限认证,将 API 文档地址修改为包含 openapi 的 URL

# 文档地址 默认为docs
DOCS_URL: str = "/openapi/docs"
# 文档关联请求数据接口
OPENAPI_URL: str = "/openapi/openapi.json"
# redoc 文档
REDOC_URL: Optional[str] = "/openapi/redoc"
  • 超级管理员

设置用户的 is_super = 1,就表示超级管理员,超级管理员拥有所有权限,可以跳过权限认证

class Authority:
    ......
    async def __call__(self, request: Request):
        """
        超级管理员不需要进行权限认证
        :param request:
        :return:
        """
        model, act = self.policy.split(',')
        e = await get_casbin()

        # 超级用户拥有所有权限
        if request.state.user.is_super:
            return

        if not await e.has_permission(request.state.user.username, model, act):
            raise AuthenticationError(err_desc=f'Permission denied: [{self.policy}]')

多配置数据库

# settings.py
DATABASE_CONNECTS = {
        'default': 'mysql://root:123456@127.0.0.1:3306/testdb'
    }

# 数据库配置
DATABASE_CONFIG: dict = {
    'connections': DATABASE_CONNECTS,
    'apps': {
        'models': {
            # 设置key值“default”的数据库连接
            'default_connection': 'default',
            'models': [
                'apps.user.model',
                'auth.casbin_tortoise_adapter'
            ]
        }
    }
}

# db_router.py
class Router:
    def db_for_read(self, model: Type[Model]):
        # 在模型定义的 Meta 中定义 default_connection 对应的数据库字符串即可
        if model._meta.default_connection:
            return model._meta.default_connection
        return "default"

    def db_for_write(self, model: Type[Model]):
        if model._meta.default_connection:
            return model._meta.default_connection
        return "default"

运行

# 进入项目目录
pipenv install

# 进入虚拟环境
pipenv run dev
MIT License Copyright (c) 2021 星星在线 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

FastAPI+MySQL+Tortoise-orm项目模板 展开 收起
Python 等 2 种语言
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Python
1
https://gitee.com/small_bud_star/FastAPI-MySQL-Tortoise-Casbin.git
git@gitee.com:small_bud_star/FastAPI-MySQL-Tortoise-Casbin.git
small_bud_star
FastAPI-MySQL-Tortoise-Casbin
FastAPI-MySQL-Tortoise-Casbin
main

搜索帮助