我的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."
我知道我不能在守卫中使用自定义功能,因此我认为不可能将其作为守卫。
请告知。
答案 0 :(得分:2)
不像Python装饰器那样优雅,但你可以使用更高阶的函数来使它更清晰。创建一个接受SessionID
,Env
,Input
的函数,以及在授权用户时应执行的回调函数,并从需要执行授权的所有函数中调用该函数检查。
(未经测试)代码:
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(因为上面的禁止回调将返回)。