[英]dj-rest-auth: ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION not working
I'm using dj-rest-auth, allauth, and simple jwt to implement authentication.我正在使用 dj-rest-auth、allauth 和简单的 jwt 来实现身份验证。
In django-allauth, setting ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION=True will automatically login user after the email is verified.在 django-allauth 中,设置 ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION=True 将在验证 email 后自动登录用户。 But posting key to "/dj-rest-auth/registration/verify-email/" only returns {"detail":"ok"}.
但是将密钥发布到“/dj-rest-auth/registration/verify-email/”只会返回 {"detail":"ok"}。
The source code below explains why:下面的源代码解释了原因:
# allauth
class ConfirmEmailView(TemplateResponseMixin, LogoutFunctionalityMixin, View):
# ...
def post(self, *args, **kwargs):
# ...
if app_settings.LOGIN_ON_EMAIL_CONFIRMATION:
resp = self.login_on_confirm(confirmation)
if resp is not None:
return resp # this is a HttpResponseRedirect object
# ...
# dj-rest-auth
class VerifyEmailView(APIView, ConfirmEmailView):
# ...
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.kwargs['key'] = serializer.validated_data['key']
confirmation = self.get_object()
confirmation.confirm(self.request)
return Response({'detail': _('ok')}, status=status.HTTP_200_OK)
Since I'm using JWT, how could I override this view to login user after verification and return access code?由于我使用的是 JWT,如何在验证后覆盖此视图以登录用户并返回访问代码?
You should take that confirmation object, write confirmation.email_address
which is a django-allauth EmailAddress model object, then get the user (ie your User model).您应该获取该确认对象,编写
confirmation.email_address
,这是一个django-allauth EmailAddress 模型对象,然后获取用户(即您的用户模型)。 All in all, just do confirmation.email_address.user
.总而言之,只需执行
confirmation.email_address.user
。 Finally, generate a JWT from the user object.最后,从用户对象生成 JWT。
To generate the proper JSON response, instantiate the LoginView class, set the user class attribute by doing view = LoginView(); view.user = confirmation.email_address.user; # TODO do view.login() but you need to customize it so that you don't call user
要生成正确的 JSON 响应,请实例化 LoginView 类,通过执行
view = LoginView(); view.user = confirmation.email_address.user; # TODO do view.login() but you need to customize it so that you don't call user
设置用户类属性view = LoginView(); view.user = confirmation.email_address.user; # TODO do view.login() but you need to customize it so that you don't call user
view = LoginView(); view.user = confirmation.email_address.user; # TODO do view.login() but you need to customize it so that you don't call user
view = LoginView(); view.user = confirmation.email_address.user; # TODO do view.login() but you need to customize it so that you don't call user
, and grab Response object by doing LoginView().get_response() view = LoginView(); view.user = confirmation.email_address.user; # TODO do view.login() but you need to customize it so that you don't call user
,并通过执行LoginView().get_response()获取 Response 对象
Make sure you check for all edge cases like if email address does not exist etc.确保检查所有边缘情况,例如电子邮件地址是否不存在等。
All in all:总而言之:
class CustomVerifyEmailView(VerifyEmailView):
# ...
def post(self, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.kwargs['key'] = serializer.validated_data['key']
confirmation = self.get_object()
confirmation.confirm(self.request)
login_view = LoginView()
login_view.user = confirmation.email_address.user
if getattr(settings, 'REST_USE_JWT', False):
self.access_token, self.refresh_token = jwt_encode(self.user)
else:
self.token = create_token(
self.token_model, self.user,
self.serializer,
)
if getattr(settings, 'REST_SESSION_LOGIN', True):
self.process_login()
return login_view.get_response()
Let us know if that works!让我们知道这是否有效!
References:参考:
I've posted this in your GitHub issue as well.我也在你的 GitHub 问题中发布了这个。 So hopefully whatever edits happen here also land there too.
所以希望这里发生的任何编辑也会在那里发生。
I had to deal with the exact same case and what seems to work quite well for me is the following我不得不处理完全相同的情况,对我来说似乎工作得很好的是以下内容
all and all my Custom view looks like this我所有的自定义视图看起来像这样
from dj_rest_auth.utils import jwt_encode
from dj_rest_auth.registration.views import VerifyEmailView
class CustomeVerifyEmailView(VerifyEmailView):
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.kwargs['key'] = serializer.validated_data['key']
confirmation = self.get_object()
confirmation.confirm(self.request)
self.access_token, self.refresh_token = jwt_encode(confirmation.email_address.user)
return Response({"refresh": str(self.refresh_token), "access": str(self.access_token)})
I got the following working based on a combination of ideas from both of the above two answers and comments on the github issue :基于以上两个答案的想法和对github 问题的评论,我得到了以下工作:
from dj_rest_auth.utils import jwt_encode
from dj_rest_auth.registration.views import VerifyEmailView, LoginView
from dj_rest_auth.registration import views
class CustomVerifyEmailView(VerifyEmailView):
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.kwargs['key'] = serializer.validated_data['key']
confirmation = self.get_object()
confirmation.confirm(self.request)
login_view = LoginView()
self.user = login_view.user = confirmation.email_address.user
if getattr(settings, 'REST_USE_JWT', False):
self.access_token, self.refresh_token = jwt_encode(self.user)
else:
#you'll have to figure this out if you need it. I didn't.
raise NotImplementedError
data = {
'user': self.user,
'access_token': self.access_token,
'refresh_token': self.refresh_token
}
login_response_serializer = login_view.get_response_serializer()
login_serializer = login_response_serializer(instance=data)
return Response(login_serializer.data, status=status.HTTP_200_OK)
views.VerifyEmailView = CustomVerifyEmailView
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.