如何精美地为Erlang中的授权用户提供一些API函数?

时间:2016-08-03 09:06:16

标签: erlang

我的API代码中有函数,其中一些函数只应将请求的结果仅返回给那些具有正确令牌的请求。如果请求未获得授权,则返回通用401响应。

我创建了一个辅助函数is_authorised(),它返回true / false。

现在,在我想让只有授权用户才能访问的函数中,我检查is_authorised()函数的结果并返回相应的响应。

以下是一个例子:

get_players(SessionID, _Env, _Input) ->
    case is_authorized(_Env) of
        true ->
            Response = [json_header(), players:select_all()];
        false ->
            Response = get_unauthorized_response()
    end,
    mod_esi:deliver(SessionID, Response).

我想知道是否可以使这种检查看起来更优雅,就像Flask中使用的Python装饰器一样。

@app.route('/user')
@required_roles('admin', 'user')
def user_page(self):
    return "You've got permission to access this page."

我知道我不能在守卫中使用自定义功能,因此我认为不可能将其作为守卫。

请告知。

2 个答案:

答案 0 :(得分:2)

不像Python装饰器那样优雅,但你可以使用更高阶的函数来使它更清晰。创建一个接受SessionIDEnvInput的函数,以及在授权用户时应执行的回调函数,并从需要执行授权的所有函数中调用该函数检查。

(未经测试)代码:

authorized(SessionID, Env, Input, Fun) ->
    Response = case is_authorized(Env) of
        true ->
            Fun();
        false ->
            get_unauthorized_response()
    end,
    mod_esi:deliver(SessionID, Response).

get_players(SessionID, Env, Input) ->
    authorized(SessionID, Env, Input, fun() ->
        [json_header(), players:select_all()]
    end).

如果要进行更广泛的检查,可以将更多参数传递给authorized。使用role_of/1函数接受Env并将角色作为原子返回,您可以允许使用以下内容访问某些用户:

authorized(SessionID, Env, Input, Roles, Fun) ->
    Response = case lists:member(role_of(Env), Roles) of
        true ->
            Fun();
        false ->
            get_unauthorized_response()
    end,
    mod_esi:deliver(SessionID, Response).

get_players(SessionID, Env, Input) ->
    authorized(SessionID, Env, Input, [admin, user], fun() ->
        [json_header(), players:select_all()]
    end).

答案 1 :(得分:0)

您可能希望了解牛仔或webmachine,因为他们会通过状态机为您提供框架来处理REST请求。实施'禁止/ 2'回调以表示未经授权的访问。

旁注:401状态代码表示在执行一个众所周知的http auth机制(如basic)时,http层的身份验证失败。另见https://en.wikipedia.org/wiki/Basic_access_authentication 您正在处理的是授权失败,该案例的正确关联http状态代码将为403(因为上面的禁止回调将返回)。

相关问题