Api 密钥和 Django Rest Framework Auth Token
Posted
技术标签:
【中文标题】Api 密钥和 Django Rest Framework Auth Token【英文标题】:Api key and Django Rest Framework Auth Token 【发布时间】:2016-07-08 04:50:18 【问题描述】:我已经在使用内置的 Django rest auth 令牌,并且我计划发布另一个 api,它将被外部集成调用以在我的 Django 应用程序中调用某些操作。问题是我想为此外部 api 调用生成另一个令牌,该调用必须与身份验证系统分开(例如 Mandrill API 密钥或 Github 个人访问令牌)。从Django rest框架authtoken
Model生成api密钥是不是很好的解决方案?
外部 api 令牌:
必须永不过期(它可能在会话身份验证系统中过期) 可以链接到用户,但不是必需的(如果链接到帐户) 可以撤销并重新激活你有释放 api 密钥的经验吗?
Django Rest Framework 有没有推荐的最佳实践?
谢谢;)
【问题讨论】:
你能分享一下你最后做了什么吗?我面临同样的限制.. 刚刚发布了我的代码作为答案***.com/a/38913644/2551769 【参考方案1】:我创建了一个新的身份验证后端和一个新的令牌模型,以避免对内置令牌行为产生副作用。
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
身份验证.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"
【讨论】:
有一个过期的时间戳,不时自动更新令牌不是更好吗?还是在您的用例中不需要它?【参考方案2】:djangorestframework-api-key
库目前可能是更好的选择。
来自文档:
Django REST Framework API Key 是一个强大的库,允许 服务器端客户端安全地使用您的 API。这些客户是 通常是第三方后端和服务(即机器) 没有用户帐户,但仍需要与您的 API 进行交互 安全的方式。
这是一种为 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 密钥。
编辑:令牌也可以撤销
【讨论】:
【参考方案3】:如果我对您的理解正确,那么Json Web Tokens 是满足您需求的解决方案。有一个非常好的 django 包可以与 django rest 框架顺利集成:django-rest-framework-jwt。
有了这个包,你可以
-
设置过期时间
重新激活或撤销密钥
从对您的 api 的每次外部调用中确定令牌是否有效
还是
希望对您有所帮助。
【讨论】:
我在 django-rest-framework-jwt 中没有发现任何撤销和重新激活行为。与 Django restauthtoken
相比,价值在哪里?
这取决于你到底想做什么。一种解决方案是从请求标头中删除 json Web 令牌。并在需要时再次添加。以上是关于Api 密钥和 Django Rest Framework Auth Token的主要内容,如果未能解决你的问题,请参考以下文章
如何解决 django rest-framework 中的错误请求
如何修复 Reactjs、Django、Django Rest Frame 工作项目中的“net::ERR_CONNECTION_REFUSED 和错误:网络错误”错误
Django REST framework框架之GET, POST, PUT, PATCH, DELETE等API请求接口设计