Api 密钥和 Django Rest Framework 授权令牌
Api key and Django Rest Framework Auth Token
我已经在使用内置的 Django rest auth 令牌,我计划发布另一个 api,外部集成将调用它来调用我的 Django 应用程序中的某些操作。问题是我想为这个外部 api 调用生成另一个令牌,它必须与身份验证系统分开(f.i。像 Mandrill API Keys 或 Github Personal Access令牌)。从 Django rest framework authtoken
模型生成 api 键是一个好的解决方案吗?
外部 api 令牌:
- 绝不能过期(它可能在会话身份验证系统中过期)
- 可以链接到用户但不是必需的(如果链接到帐户)
- 可以撤销并重新激活
您有释放 api 密钥的经验吗?
是否有 Django Rest Framework 推荐的最佳实践?
谢谢 ;)
如果我没理解错的话,那么Json Web Tokens is the solution for your needs. There is a really good django package available that integrates smoothly with django rest framework: django-rest-framework-jwt。
有了这个包,您可以
- 设置过期时间
- 重新激活或撤销密钥
- 从对您的 api 的每次外部调用中确定令牌是否有效
还是
希望对您有所帮助。
我创建了一个新的身份验证后端和一个新的令牌模型,以避免对内置令牌行为产生副作用。
models.py
class ApiKeyToken(models.Model):
key = models.CharField(max_length=40, primary_key=True)
company = models.ForeignKey(Company)
is_active = models.BooleanField(default=True)
def save(self, *args, **kwargs):
if not self.key:
self.key = self.generate_key()
return super(ApiKeyToken, self).save(*args, **kwargs)
def generate_key(self):
return binascii.hexlify(os.urandom(20)).decode()
def __unicode__(self):
return self.key
authentication.py
class ApiKeyAuthentication(TokenAuthentication):
def get_token_from_auth_header(self, auth):
auth = auth.split()
if not auth or auth[0].lower() != b'api-key':
return None
if len(auth) == 1:
raise AuthenticationFailed('Invalid token header. No credentials provided.')
elif len(auth) > 2:
raise AuthenticationFailed('Invalid token header. Token string should not contain spaces.')
try:
return auth[1].decode()
except UnicodeError:
raise AuthenticationFailed('Invalid token header. Token string should not contain invalid characters.')
def authenticate(self, request):
auth = get_authorization_header(request)
token = self.get_token_from_auth_header(auth)
if not token:
token = request.GET.get('api-key', request.POST.get('api-key', None))
if token:
return self.authenticate_credentials(token)
def authenticate_credentials(self, key):
try:
token = ApiKeyToken.objects.get(key=key)
except ApiKeyToken.DoesNotExist:
raise AuthenticationFailed('Invalid Api key.')
if not token.is_active:
raise AuthenticationFailed('Api key inactive or deleted.')
user = token.company.users.first() # what ever you want here
return (user, token)
然后您可以通过以下方式请求安全 api:
curl http://example.com/api/your-awesome-api.json -H "Authorization: Api-Key {token}"
djangorestframework-api-key
库目前可能是更好的选择。
来自文档:
Django REST Framework API Key is a powerful library for allowing
server-side clients to safely use your API. These clients are
typically third-party backends and services (i.e. machines) which do
not have a user account but still need to interact with your API in a
secure way.
这是一种为 Django REST Framework 项目手动或以编程方式发布新 API 密钥的良好支持且易于使用的方式。
最简单的集成:
# settings.py
INSTALLED_APPS = [
# ...
"rest_framework",
"rest_framework_api_key",
]
python manage.py migrate
# settings.py
REST_FRAMEWORK = {
"DEFAULT_PERMISSION_CLASSES": [
"rest_framework_api_key.permissions.HasAPIKey",
]
}
然后您可以通过管理界面或通过 rest_framework_api_key.models.APIKey
对象以编程方式创建新的 API 密钥。
编辑:令牌也可以被撤销
我已经在使用内置的 Django rest auth 令牌,我计划发布另一个 api,外部集成将调用它来调用我的 Django 应用程序中的某些操作。问题是我想为这个外部 api 调用生成另一个令牌,它必须与身份验证系统分开(f.i。像 Mandrill API Keys 或 Github Personal Access令牌)。从 Django rest framework authtoken
模型生成 api 键是一个好的解决方案吗?
外部 api 令牌:
- 绝不能过期(它可能在会话身份验证系统中过期)
- 可以链接到用户但不是必需的(如果链接到帐户)
- 可以撤销并重新激活
您有释放 api 密钥的经验吗?
是否有 Django Rest Framework 推荐的最佳实践?
谢谢 ;)
如果我没理解错的话,那么Json Web Tokens is the solution for your needs. There is a really good django package available that integrates smoothly with django rest framework: django-rest-framework-jwt。
有了这个包,您可以
- 设置过期时间
- 重新激活或撤销密钥
- 从对您的 api 的每次外部调用中确定令牌是否有效
还是
希望对您有所帮助。
我创建了一个新的身份验证后端和一个新的令牌模型,以避免对内置令牌行为产生副作用。
models.py
class ApiKeyToken(models.Model):
key = models.CharField(max_length=40, primary_key=True)
company = models.ForeignKey(Company)
is_active = models.BooleanField(default=True)
def save(self, *args, **kwargs):
if not self.key:
self.key = self.generate_key()
return super(ApiKeyToken, self).save(*args, **kwargs)
def generate_key(self):
return binascii.hexlify(os.urandom(20)).decode()
def __unicode__(self):
return self.key
authentication.py
class ApiKeyAuthentication(TokenAuthentication):
def get_token_from_auth_header(self, auth):
auth = auth.split()
if not auth or auth[0].lower() != b'api-key':
return None
if len(auth) == 1:
raise AuthenticationFailed('Invalid token header. No credentials provided.')
elif len(auth) > 2:
raise AuthenticationFailed('Invalid token header. Token string should not contain spaces.')
try:
return auth[1].decode()
except UnicodeError:
raise AuthenticationFailed('Invalid token header. Token string should not contain invalid characters.')
def authenticate(self, request):
auth = get_authorization_header(request)
token = self.get_token_from_auth_header(auth)
if not token:
token = request.GET.get('api-key', request.POST.get('api-key', None))
if token:
return self.authenticate_credentials(token)
def authenticate_credentials(self, key):
try:
token = ApiKeyToken.objects.get(key=key)
except ApiKeyToken.DoesNotExist:
raise AuthenticationFailed('Invalid Api key.')
if not token.is_active:
raise AuthenticationFailed('Api key inactive or deleted.')
user = token.company.users.first() # what ever you want here
return (user, token)
然后您可以通过以下方式请求安全 api:
curl http://example.com/api/your-awesome-api.json -H "Authorization: Api-Key {token}"
djangorestframework-api-key
库目前可能是更好的选择。
来自文档:
Django REST Framework API Key is a powerful library for allowing server-side clients to safely use your API. These clients are typically third-party backends and services (i.e. machines) which do not have a user account but still need to interact with your API in a secure way.
这是一种为 Django REST Framework 项目手动或以编程方式发布新 API 密钥的良好支持且易于使用的方式。
最简单的集成:
# settings.py
INSTALLED_APPS = [
# ...
"rest_framework",
"rest_framework_api_key",
]
python manage.py migrate
# settings.py
REST_FRAMEWORK = {
"DEFAULT_PERMISSION_CLASSES": [
"rest_framework_api_key.permissions.HasAPIKey",
]
}
然后您可以通过管理界面或通过 rest_framework_api_key.models.APIKey
对象以编程方式创建新的 API 密钥。
编辑:令牌也可以被撤销