fastapi和Propelauth的RBAC授权
#网络开发人员 #python #安全 #startup

基于角色的访问控制(RBAC)是一种决定谁访问其角色的方法。

举例来说,假设我们正在构建一种产品,该产品允许团队与他们的同事聊天。在团队中,每个用户都是 Admin 成员。我们希望让所有用户查看/发送聊天消息( admin s和会员 s),但只有 admin 的才能更新计费信息。这是RBAC的简单形式。

Roles

让我们以相同的示例,用代码写出并解释其工作原理:

import os
from dotenv import load_dotenv
from fastapi import Depends, FastAPI
from propelauth_fastapi import init_auth, User

load_dotenv()

app = FastAPI()
auth = init_auth(os.getenv("PROPELAUTH_AUTH_URL"), os.getenv("PROPELAUTH_API_KEY"))

@app.get("/api/org/{org_id}/messages")
async def view_messages(org_id: str, current_user: User = Depends(auth.require_user)):
    org = auth.require_org_member(current_user, org_id)
    return fetch_messages(org.org_id)

@app.get("/api/org/{org_id}/billing")
async def view_billing(org_id: str, current_user: User = Depends(auth.require_user)):
    org = auth.require_org_member_with_minimum_role(current_user, org_id, "Admin")
    return fetch_billing_info(org.org_id)

init_auth做什么?

init_auth从Propelauth获取元数据,该元数据将用于验证用户。它一次在启动时执行此操作,以便可以在不提出任何外部请求的情况下验证用户。

require_user如何工作?

当您的前端向后端提出请求时,它将为提出请求的用户提供一个令牌。 require_user验证此令牌(使用它在init_auth中获取的元数据),并将用户注入请求中。如果提供了无效的凭据,请拒绝请求。

什么是org_id?

这是组织的标识符。 Propelauth提供B2B身份验证,这意味着您的用户可以创建组织,邀请他们的同事加入他们并在组织中管理角色。

用户和org_id来自哪里?

Propelauth提供端到端的身份验证,其中一个组件是可配置的UI(托管在域上)供您的用户注册。另一个方面是用于创建/加入组织,邀请同事向这些组织的UI,并让这些用户管理其组织内的权限。

Pick roles

用户正在管理ACME组织的自定义UI

用户注册后,创建了一个安全的,仅HTTP的cookie。我们提供frontend libraries,以便您的前端可以理解用户当前是否基于该cookie登录。这些库还可以获取用户是当前用户的成员或短暂令牌的组织 - 后端可以验证并了解谁提出了请求。

例如,在React中,这可能是这样的:

import {withAuthInfo} from "@propelauth/react";
import {useEffect, useState} from "react";

// accessToken and orgHelper are automatically injected from withAuthInfo
function AuthenticatedRequestToBilling({accessToken, orgHelper}) {
    const [response, setResponse] = useState(null)

    // A user can be in multiple orgs - get the one they are currently interacting with
    const selectedOrg = orgHelper.useActiveOrg()
    useEffect(() => {
        fetchBilling(accessToken, selectedOrg?.orgId).then(setResponse)
    }, [accessToken, selectedOrg?.orgId])

    return <span>
        <h2>Server Response</h2>
        <pre>{response ? JSON.stringify(response, null, 2) : "Loading..."}</pre>
    </span>
}

function fetchBilling(accessToken, orgId) {
    return fetch(`/api/org/${orgId}/billing`, {
        headers: {
            "Content-Type": "application/json",
            "Authorization": `Bearer ${accessToken}`
        }
    }).then(response => {
        if (response.ok) {
            return response.json()
        } else {
            return {status: response.status}
        }
    })
}

export default withAuthInfo(AuthenticatedRequestToBilling);

您不必担心管理邀请函,设计电子邮件或处理角色更改 - 所有这些都已经提供了。

如果用户不是该组织的成员会发生什么?

require_org_member将失败并拒绝该请求。这是在令牌中编码的,因此也不会提出任何外部请求。

如果您有兴趣使用PropelAuth,可以注册here或在support@propelauth.com伸出手,我们很乐意回答您的任何问题。