Django Rest Framework 基于密钥的访问

Key based access for the Django Rest Framework

假设获取用户列表的 API 端点是这个

/api_auth/user/

但我想将此列表的访问权限限制为 api_key

的人
 /api_auth/user/?access_key=$omeRandomHash3252532

如何使用 Django Rest Framework 实现这样的访问系统?

我应该使用权限来实现吗?

如果您可以在请求中设置 header,则可以使用 Rest Framework's Token Authentication

否则,如果您需要将其作为 GET 参数放入 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)

django-rest-framework 不支持开箱即用,但可以轻松实现:

如果您查看 http://www.django-rest-framework.org/api-guide/authentication/,您将看到自定义身份验证方法的示例。在此基础上,你需要实现这样的东西:

from django.contrib.auth.models import User
from rest_framework import authentication
from rest_framework import exceptions

class APIKeyAuthentication(authentication.BaseAuthentication):
    def authenticate(self, request):
        api_key = request.GET.get('api_key')
        if not api_key:
            return None

        try:
            user = get_user_from_api_key(api_key)
        except User.DoesNotExist:
            raise exceptions.AuthenticationFailed('No user for API KEY')

        return (user, None)

APIKeyAuthentication 应该放在 authentication.py 模块上,并在 settings.py 上配置 REST_FRAMEWORK 设置,像这样

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'my_custom_package.authentication.APIKeyAuthentication',
    )
}

现在,上面所做的是检查 api_key 参数是否存在(如果不存在,它将 return None 检查请求是否可以通过不同的方式进行身份验证 - - 如果您不想检查任何其他身份验证 classes 那么只需像我们在下面找不到用户时那样引发 exceptions.AuthenticationFailed 异常。现在,我们需要实现 get_user_from_api_key 函数,它将 return 来自 API_KEY 的 User 实例。如果找到与传递的 api_key 相关的用户,那么它将被 returned , 否则将抛出 exceptions.AuthenticationFailed 异常。

关于get_user_from_api_key功能,其实现取决于您的要求。例如,如果您想为每个用户创建一个新的 api 密钥,您应该创建一个 APIKey 模型,该模型将具有 api_key CharFieldForeignKey 到具有此 api_keyUser。然后 get_user_from_api_key 函数将查询 APIKey 模型以获取具有提供的 api_key.

的用户

更新

如果你想使用 django-rest-framework 权限而不是身份验证,你可以创建一个 APIKeyPermission class 像这样:


from rest_framework import permissions

class APIKeyPermission(permissions.BasePermission):
    def has_permission(self, request, view):
        api_key = request.GET.get('api_key')
        return check_permission(api_key, request)

其中 check_permission 函数将检查传递的 api_key 是否具有该特定请求的权限。请查看 http://www.django-rest-framework.org/api-guide/permissions/ 上的示例以获取更多信息 - 您可以选择实施 has_object_permission 来实施对象级权限而不是视图级权限。