🌲[bamboo] 用户认证和权限管理

grey 正解

了然

我倾向于使用JWT来认证和鉴权,但是JWT签发后是无法撤回的(服务端不保存用户的登录状态)。在这方面有什么要求吗?

为啥要撤回呢?什么情况要撤回?比方说废弃了用户那服务端可以拒绝token。

如果是改了密码的情况确实取消不了登录状态,但我觉得这不是大问题。一般密码是只能本人改的,这样前端就可以主动清除登录态

因为有些场景下,比如单点登录(SSO),需要用户限制用户只在一个终端登录,所以可能存在需要将用户原有登陆状态过期的需求(比如不能同时在两台PC上登录QQ)。
既然,咱们不存在这个需求,那就不需要考虑这个了

我稍晚一些把方案发上来,您和辉哥评审一下。等到项目标准化完成后,我再开始写代码

一、认证部分

这是大致的认证流程:
认证流程

1.用户使用用户名、密码登录;登录成功,则服务端签发access_token和refresh_token
(我的个人习惯是access_token有效期为30min,refresh_token为7day)

2.客户端每次请求时,带上access_token进行认证和授权(不携带refresh_token)

3.当access_token过期时,客户端可以通过refresh_token获取新的access_token

4.refresh_token过期时,用户需要重新登录

如果需要简化,我们可以去掉refresh_token,延长access_token的时效。当access_token过期时,直接重新登录

二、授权部分

授权使用,flask-httpauth

1.单权限

@app.route('/manage-content')
@auth.login_required(role=MANAGE_CONTENT)
def manage_content_only():
    ...

2.多权限

@app.route('/multi-permissions')
@auth.login_required(role=[[MANAGE_CONTENT, MANAGE_USER]])
def multi_permissions():
    ...

3.获取当前用户权限

@auth.get_user_roles
def get_user_roles(user):
    user_permissions = []
    for permission in permissions:
        if user.permissions & permission:
            user_permissions.append(permission)
    return user_permissions

flask-httpauth的授权是基于角色的,如果要把参数名改为permission,我们可以fork一份代码自己修改。
作者不会介意…吧?

HTTPAuth在OpenAPI上有问题吧

不能通过APIFlask的能力解决吗?

支持HTTPBasicAuth,不支持HTTPTokenAuth。
可以单独给OpenAPI写一个认证逻辑。

实际上apiflask的security部分也是使用的Flask-HTTPAuth @frostming

这似乎多一层中括号?其他没问题

另外名字改成auth_required,因为可能后面会支持API key

不加中括号,多权限关系是any,只要满足一个就行;加了是and,必须具有列表里的所有权限才行
不用列表,用元组也可以

改名这个简单:

auth.auth_required = auth.login_required

另外,role这个参数名需要修改为permission吗

any的话用位或就可以: MANAGE_CONTENT | MANAGE_USER 即表示满足任意一个,目前不会有太复杂的逻辑关系式

role改成permission更恰当

需要使用双token机制吗?还是只使用access_token即可 @frostming 为什么使用双token

双token吧

这个权限表示方式是Flask-HTTPAuth的,不过我们可以修改

哦,如果是支持的,就不用费劲改了

role和权限的表示方式都是Flask-HTTPAuth定义的

我试了一下,修改并不复杂

我个人建议还是修改一下,这样一致性会更好

auth.current_user中需要包含哪些信息?

一般只存放用户的唯一标识,如 ID。