Django Rest 框架的基于密钥的访问
Posted
技术标签:
【中文标题】Django Rest 框架的基于密钥的访问【英文标题】:Key based access for the Django Rest Framework 【发布时间】:2015-02-02 09:44:51 【问题描述】:假设获取用户列表的 API 端点是这样的
/api_auth/user/
但我想限制只有拥有 api_key
的人才能访问此列表 /api_auth/user/?access_key=$omeRandomHash3252532
如何使用 Django Rest Framework 实现这样的访问系统?
我应该使用权限来实现吗?
【问题讨论】:
【参考方案1】:django-rest-framework 不支持开箱即用,但可以轻松实现:
如果您查看http://www.django-rest-framework.org/api-guide/authentication/,您会看到自定义身份验证方法的示例。基于此,您需要实现以下内容:
从 django.contrib.auth.models 导入用户 从 rest_framework 导入认证 从 rest_framework 导入异常 类 APIKeyAuthentication(authentication.BaseAuthentication): def 身份验证(自我,请求): api_key = request.GET.get('api_key') 如果不是 api_key: 返回无 尝试: 用户 = get_user_from_api_key(api_key) 除了 User.DoesNotExist: raise exceptions.AuthenticationFailed('API KEY 没有用户') 返回(用户,无)APIKeyAuthentication
应该放在 authentication.py 模块上,并在 settings.py 上配置REST_FRAMEWORK
设置,像这样
现在,上面所做的是检查 api_key
参数是否存在(如果不存在,它将返回 None 以检查请求是否可以通过不同的方式进行身份验证——如果您不想检查任何其他身份验证类然后只引发exceptions.AuthenticationFailed
异常,就像我们在下面找不到用户时所做的那样。现在,我们需要实现一个get_user_from_api_key
函数,该函数将从API_KEY 返回一个User
实例。如果与相关的用户传过来的 api_key 找到了就会返回,如果没有就会抛出exceptions.AuthenticationFailed
exception。
关于get_user_from_api_key
函数,其实现取决于您的要求。例如,如果您想为每个用户创建一个新的 api 密钥,您应该创建一个 APIKey
模型,该模型将具有一个 api_key
CharField
和一个 ForeignKey
到具有此 api_key
的 User
.然后get_user_from_api_key
函数将查询APIKey
模型以获取具有提供的api_key
的用户。
更新
如果你想使用 django-rest-framework 权限而不是身份验证,你可以像这样创建一个APIKeyPermission
类:
check_permission
函数将检查传递的 api_key 是否具有该特定请求的权限。请查看 http://www.django-rest-framework.org/api-guide/permissions/ 上的示例以获取更多信息 - 您可以选择实施 has_object_permission
来实施对象级权限而不是视图级权限。
【讨论】:
感谢您的回答,但我感觉我可能需要使用权限来实现这一点。请检查问题中的编辑。 你指的是django权限还是django-rest-framework权限? 嘿,这行得通。知道如何将它添加到我的所有 APIView 中吗? > 应该放在 authentication.py 模块上并配置 @Serafeim 这个文件在哪里?我找不到它。 @volatil3,没地方,这是你自己添加的模块:)【参考方案2】:如果您能够在请求中设置标头,则可以使用Rest Framework's Token Authentication。
否则,如果您需要将其作为GET
-paramter 放入URL 中,您可以创建自己的custom authentication class:
from rest_framework.authentication import TokenAuthentication
class MyAuthentication(TokenAuthentication):
def authenticate(self, request):
token = request.GET.get('api-key', None)
if token is None:
return None
return self.authenticate_credentials(token)
【讨论】:
感谢您的回答,但我觉得我可能需要使用权限来实现这一点。请检查问题中的编辑。 也许能解释一下为什么“你有感觉”你需要权限? 我不想将此访问机制绑定到特定用户,而是绑定到对 API 的所有请求。 好吧听起来你应该使用权限! 知道如何在所有 APIView 中添加单个自定义权限吗?以上是关于Django Rest 框架的基于密钥的访问的主要内容,如果未能解决你的问题,请参考以下文章
如何从 django rest 框架访问 jwt 令牌到 Angular 前端
Django rest-framework框架-访问频率控制