iMerica / dj-rest-auth

Authentication for Django Rest Framework
https://dj-rest-auth.readthedocs.io/en/latest/index.html
MIT License
1.66k stars 310 forks source link

Registration only works on the second attempt - [Errno 99] Cannot assign requested address #510

Open LoSaMe opened 1 year ago

LoSaMe commented 1 year ago

When calling the code to register a user, the API initially returns a status 500 error. However, despite the error, the user is still created. Afterwards, when i delete this user and the registration code is executed again, the call is successful with a status of 201. The frontend (Vue.js) and Django are Docker containers. However, only the registration is problematic. Tried with dj-rest-auth 2.2.5 and 4.0.1.

curl -X POST -H "Content-Type: application/json" -d '{
  "username": "bob3",
  "email": "bob3@bob.de",
  "password1": "Kennwort1!",
  "password2": "Kennwort1!"
}' http://greenit:8000/api/registration/

That is the error message: grafik

Traceback:

Environment:

Request Method: POST
Request URL: http://greenit:8000/api/registration/

Django Version: 4.0.3
Python Version: 3.11.3
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'APITest',
 'corsheaders',
 'rest_framework',
 'rest_framework.authtoken',
 'dj_rest_auth',
 'django.contrib.sites',
 'allauth',
 'allauth.account',
 'allauth.socialaccount',
 'dj_rest_auth.registration']
Installed Middleware:
['corsheaders.middleware.CorsMiddleware',
 'django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']

Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python3.11/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/usr/local/lib/python3.11/site-packages/django/views/generic/base.py", line 84, in view
    return self.dispatch(request, *args, **kwargs)
  File "/usr/local/lib/python3.11/site-packages/django/utils/decorators.py", line 46, in _wrapper
    return bound_method(*args, **kwargs)
  File "/usr/local/lib/python3.11/site-packages/django/views/decorators/debug.py", line 92, in sensitive_post_parameters_wrapper
    return view(request, *args, **kwargs)
  File "/usr/local/lib/python3.11/site-packages/dj_rest_auth/registration/views.py", line 42, in dispatch
    return super().dispatch(*args, **kwargs)
  File "/usr/local/lib/python3.11/site-packages/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "/usr/local/lib/python3.11/site-packages/rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/usr/local/lib/python3.11/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
  File "/usr/local/lib/python3.11/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "/usr/local/lib/python3.11/site-packages/rest_framework/generics.py", line 190, in post
    return self.create(request, *args, **kwargs)
  File "/usr/local/lib/python3.11/site-packages/dj_rest_auth/registration/views.py", line 64, in create
    user = self.perform_create(serializer)
  File "/usr/local/lib/python3.11/site-packages/dj_rest_auth/registration/views.py", line 90, in perform_create
    complete_signup(
  File "/usr/local/lib/python3.11/site-packages/allauth/account/utils.py", line 186, in complete_signup
    return perform_login(
  File "/usr/local/lib/python3.11/site-packages/allauth/account/utils.py", line 168, in perform_login
    response = adapter.pre_login(request, user, **hook_kwargs)
  File "/usr/local/lib/python3.11/site-packages/allauth/account/adapter.py", line 409, in pre_login
    send_email_confirmation(request, user, signup=signup, email=email)
  File "/usr/local/lib/python3.11/site-packages/allauth/account/utils.py", line 319, in send_email_confirmation
    email_address.send_confirmation(request, signup=signup)
  File "/usr/local/lib/python3.11/site-packages/allauth/account/models.py", line 59, in send_confirmation
    confirmation.send(request, signup=signup)
  File "/usr/local/lib/python3.11/site-packages/allauth/account/models.py", line 166, in send
    get_adapter(request).send_confirmation_mail(request, self, signup)
  File "/usr/local/lib/python3.11/site-packages/allauth/account/adapter.py", line 549, in send_confirmation_mail
    self.send_mail(email_template, emailconfirmation.email_address.email, ctx)
  File "/usr/local/lib/python3.11/site-packages/allauth/account/adapter.py", line 140, in send_mail
    msg.send()
  File "/usr/local/lib/python3.11/site-packages/django/core/mail/message.py", line 298, in send
    return self.get_connection(fail_silently).send_messages([self])
  File "/usr/local/lib/python3.11/site-packages/django/core/mail/backends/smtp.py", line 124, in send_messages
    new_conn_created = self.open()
  File "/usr/local/lib/python3.11/site-packages/django/core/mail/backends/smtp.py", line 80, in open
    self.connection = self.connection_class(
  File "/usr/local/lib/python3.11/smtplib.py", line 255, in __init__
    (code, msg) = self.connect(host, port)
  File "/usr/local/lib/python3.11/smtplib.py", line 341, in connect
    self.sock = self._get_socket(host, port, self.timeout)
  File "/usr/local/lib/python3.11/smtplib.py", line 312, in _get_socket
    return socket.create_connection((host, port), timeout,
  File "/usr/local/lib/python3.11/socket.py", line 851, in create_connection
    raise exceptions[0]
  File "/usr/local/lib/python3.11/socket.py", line 836, in create_connection
    sock.connect(sa)

Exception Type: OSError at /api/registration/
Exception Value: [Errno 99] Cannot assign requested address
MuhammadAnas47 commented 5 months ago

getting same issue for me as well.

flange-ipb commented 5 months ago

Looks like your SMTP backend isn't properly configured.

MuhammadAnas47 commented 5 months ago

I think the dj-rest-auth registration views need a exception handling to avoid this issue.

Looks like your SMTP backend isn't properly configured.

flange-ipb commented 5 months ago

Well, catching exceptions is a very delicate topic.

I'm writing an argument against doing this: My personal web dev history is mostly JavaEE stuff where I'm used to have all business logic calls as a transaction, which is guaranteed by the EJB component model. A single transaction can be changes in the database, sending an email for instance, or - in our scenario - both (typically database first, then send email). If an exception is thrown inside such an EJB call, the whole transaction has to be rolled back. I.e. if the email delivery to the upstream SMTP server fails, then the database changes have to be rolled back. The HTTP response should be something in the 500 range, but that's the task of the servlet that triggered the EJB call and that is receiving the exception.

Now, back to Django: With default configuration there are no transactions. With some configuration, transactions on the level of a single HTTP request are possible and the developer can decide what to do in case an exception pops up. Is dj-rest-auth going to anticipate that everyone uses the default behaviour? To me, catching an exception too early is paternalism. Libraries shouldn't do this. If you don't want to see the exception, then simply override the behaviour of the appropriate view by inheritance.

MuhammadAnas47 commented 4 months ago

I tried with below settings,

ACCOUNT_EMAIL_REQUIRED = True ACCOUNT_AUTHENTICATION_METHOD = 'username' ACCOUNT_EMAIL_VERIFICATION = "mandatory"

Now I can able to register the user.

//output { "detail": "Verification e-mail sent." }

But if I click the link that user must verify email, it showing below errors.

ImproperlyConfigured at /dj-rest-auth/registration/account-confirm-email/NTc:1s5ep8:fN6f-dfGaKRKCGCOo8w9mpqWwTUZM-KpuJ9jK_Il9lo/

TemplateResponseMixin requires either a definition of 'template_name' or an implementation of 'get_template_names()'