没有用户模型的 Django 基于令牌的身份验证
Django's Token based Authentication without User model
我正在使用基于 Django 令牌的身份验证。 (JWT Token 由 AWS Cognito 等第三方服务生成,我们只会验证签名和过期时间)。
此 REST 应用程序将没有任何用户模型,使用 API 调用的任何人都需要仅通过 JWT 令牌进行身份验证。
class JSONWebTokenAuthentication(TokenAuthentication):
def authenticate_credentials(self, jwtToken):
try:
payload = jwt.decode(jwtToken, secret_key,verify=True)
# user = User.objects.get(username='root')
user = AnonymousUser()
except (jwt.DecodeError, User.DoesNotExist):
raise exceptions.AuthenticationFailed('Invalid token')
except jwt.ExpiredSignatureError:
raise exceptions.AuthenticationFailed('Token has expired')
return (user, payload)
浏览量:
@api_view(["POST"])
@authentication_classes((JSONWebTokenAuthentication,))
@permission_classes((AllowAny,))
以上过程根本没有跟踪Token。 With/Without 令牌,API 调用正常。如果我进行如下两个更改,它就可以工作了。
user = User.objects.get(username='root')
#user = AnonymousUser()
@permission_classes((IsAuthenticated,))
一种方法是,在我的应用程序中至少有一个用户并引用该用户[此网络应用程序可能会在需要时扩展到任意数量的实例,因此插入具有相同“用户名”的相同用户必须自动化。 ].但是,我可以消除身份验证中的“用户”概念吗?
Django REST framework 在很大程度上假定请求是基于用户进行身份验证的,但它们确实提供了对身份验证匿名请求的支持。但它通过为匿名用户提供某些权限而从 "verifying (django) user is genuine" 的标准假设中脱颖而出。第一个案例的问题是 "Allow Any" 的权限装饰器。
我建议有一个虚拟的 Django 用户。 (它也不会阻止您扩展到任意数量的实例)。
使用
user = User.objects.get_or_create(username='whatever')[0]
而不是
user = AnonymousUser()
现在将权限装饰器更改为
@permission_classes((IsAuthenticated,))
除非您设置密码,否则任何人都无法登录此用户,而且作为此用户登录后您将无法访问您的 API 电话。访问您的 API 的唯一方法是发送有效的令牌。
希望对您有所帮助。
使用 django-rest-framework-simplejwt you can set DEFAULT_AUTHENTICATION_CLASSES
to use JWTTokenUserAuthentication 并在没有用户的情况下验证令牌。
有时您真的不需要用户,例如,服务器到服务器的通信。这是一个解决方案。
覆盖 AnonymousUser 的 is_authenticated 属性 就可以了
from django.contrib.auth.models import AnonymousUser
class ServerUser(AnonymousUser):
@property
def is_authenticated(self):
# Always return True. This is a way to tell if
# the user has been authenticated in permissions
return True
只需return您自定义身份验证中的这种新型用户
class CustomServerAuthentication(authentication.BaseAuthentication):
keyword = 'Token'
def authenticate(self, request):
auth = get_authorization_header(request).split()
if not auth or auth[0].lower() != self.keyword.lower().encode():
return None
if len(auth) == 1:
raise exceptions.AuthenticationFailed('Invalid token header. No credentials provided.')
elif len(auth) > 2:
raise exceptions.AuthenticationFailed('Invalid token header. Token string should not contain spaces.')
token = auth[1].decode()
if not (settings.CUSTOM_SERVER_AUTH_TOKEN == token):
raise exceptions.AuthenticationFailed('You do not have permission to access this resource')
user = ServerUser()
return user, None
您可以在不向数据库插入数据的情况下使用用户模型
使用:
user = User(id=22,username="someone")
而不是:
user = User.objects.get_or_create(username="someone")
或
AnonymousUser()
我正在使用基于 Django 令牌的身份验证。 (JWT Token 由 AWS Cognito 等第三方服务生成,我们只会验证签名和过期时间)。
此 REST 应用程序将没有任何用户模型,使用 API 调用的任何人都需要仅通过 JWT 令牌进行身份验证。
class JSONWebTokenAuthentication(TokenAuthentication):
def authenticate_credentials(self, jwtToken):
try:
payload = jwt.decode(jwtToken, secret_key,verify=True)
# user = User.objects.get(username='root')
user = AnonymousUser()
except (jwt.DecodeError, User.DoesNotExist):
raise exceptions.AuthenticationFailed('Invalid token')
except jwt.ExpiredSignatureError:
raise exceptions.AuthenticationFailed('Token has expired')
return (user, payload)
浏览量:
@api_view(["POST"])
@authentication_classes((JSONWebTokenAuthentication,))
@permission_classes((AllowAny,))
以上过程根本没有跟踪Token。 With/Without 令牌,API 调用正常。如果我进行如下两个更改,它就可以工作了。
user = User.objects.get(username='root')
#user = AnonymousUser()
@permission_classes((IsAuthenticated,))
一种方法是,在我的应用程序中至少有一个用户并引用该用户[此网络应用程序可能会在需要时扩展到任意数量的实例,因此插入具有相同“用户名”的相同用户必须自动化。 ].但是,我可以消除身份验证中的“用户”概念吗?
Django REST framework 在很大程度上假定请求是基于用户进行身份验证的,但它们确实提供了对身份验证匿名请求的支持。但它通过为匿名用户提供某些权限而从 "verifying (django) user is genuine" 的标准假设中脱颖而出。第一个案例的问题是 "Allow Any" 的权限装饰器。
我建议有一个虚拟的 Django 用户。 (它也不会阻止您扩展到任意数量的实例)。
使用
user = User.objects.get_or_create(username='whatever')[0]
而不是
user = AnonymousUser()
现在将权限装饰器更改为
@permission_classes((IsAuthenticated,))
除非您设置密码,否则任何人都无法登录此用户,而且作为此用户登录后您将无法访问您的 API 电话。访问您的 API 的唯一方法是发送有效的令牌。
希望对您有所帮助。
使用 django-rest-framework-simplejwt you can set DEFAULT_AUTHENTICATION_CLASSES
to use JWTTokenUserAuthentication 并在没有用户的情况下验证令牌。
有时您真的不需要用户,例如,服务器到服务器的通信。这是一个解决方案。
覆盖 AnonymousUser 的 is_authenticated 属性 就可以了
from django.contrib.auth.models import AnonymousUser
class ServerUser(AnonymousUser):
@property
def is_authenticated(self):
# Always return True. This is a way to tell if
# the user has been authenticated in permissions
return True
只需return您自定义身份验证中的这种新型用户
class CustomServerAuthentication(authentication.BaseAuthentication):
keyword = 'Token'
def authenticate(self, request):
auth = get_authorization_header(request).split()
if not auth or auth[0].lower() != self.keyword.lower().encode():
return None
if len(auth) == 1:
raise exceptions.AuthenticationFailed('Invalid token header. No credentials provided.')
elif len(auth) > 2:
raise exceptions.AuthenticationFailed('Invalid token header. Token string should not contain spaces.')
token = auth[1].decode()
if not (settings.CUSTOM_SERVER_AUTH_TOKEN == token):
raise exceptions.AuthenticationFailed('You do not have permission to access this resource')
user = ServerUser()
return user, None
您可以在不向数据库插入数据的情况下使用用户模型 使用:
user = User(id=22,username="someone")
而不是:
user = User.objects.get_or_create(username="someone")
或
AnonymousUser()