How do I implement the built in views for password-reset in the django.rest.auth and how do I create an email verification system for registration using the django rest framework and angularjs?
I have been searching for a tutorial or some good documentation that on how to implement django's send_email function in a website using the django rest framework and angular js but I haven't been able to find any.
What I need...
when a new user registers a url must be generated for them to confirm their email address
this url must be automatically sent to the user's given email
after the user is sent to this link and confirms their email address their status must be changed from new_user.is_active = False to new_user.is_active = True
What I have...
registration form that sends a post request to my register endpoint
the new user data is then unpacked, validated, and saved in my register view
in settings.py i have added this...
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'myemail#gmail.com'
EMAIL_HOST_PASSWORD = 'mypassword'
EMAIL_PORT = 587
in my urls.py i have added this...
from django.conf.urls import url
from rest_auth.views import PasswordResetView, PasswordResetConfirmView
urlpatterns = [
url(r'^password/reset/$', PasswordResetView.as_view(), name='password_reset'),
url(r'^password/reset/confirm/$', PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
]
So my question is how do I implement these views and urls to my project and how to I create email confirmation using the from django.core.mail import send_mail
Thanks in advance
After the user fills the registration form you could ask for a verification code. This verification code will be sent to the email address provided in the registration form. On correctly entering the verification code you can set the users to active.
For anyone still looking for solutions, django-allauth is a good choice. you can override PASSWORD_RESET_CONFIRM_SERIALIZER to make the user active.
Related
I cannot wrap my head around this problem. Read a lot of solutions but cannot seem to find the correct combination that works for me.
I want to initiate a users password reset flow from within my (android/iOS) app.
I think I need django-rest-auth for this to expose an API endpoint something like this:
from rest_auth.views import PasswordResetView
urlpatterns = [
path('password/reset/', PasswordResetView.as_view(), name='rest_password_reset'),
]
Now posting to http://127.0.0.1:8000/password/reset/ with a JSON payload of { "email": "test1#test.com" } gives an error: django.urls.exceptions.NoReverseMatch: Reverse for 'password_reset_confirm' not found.
Now, I'm strugeling with the next part. I found that password_reset_confirm is defined in django.contrib.auth but I do not want to expose the admin-like interface to the user.
I'd like to use the allauth PasswordResetFromKeyView.
So, defining password_reset_confirm as:
path('password/reset/<uidb64>/<token>/',
PasswordResetFromKeyView.as_view(),
name='password_reset_confirm'
),
Works. An email is send containing a reset URL. But now, following that URL I'm getting another error: PasswordResetFromKeyView.dispatch() missing 2 required positional arguments: 'uidb36' and 'key'
Ok, obvious, changed the password_reset_confirm path arguments from <uidb64> and <token> to <uidb36> and <key>.
Than the error moves to password_reset_email.html because of the arguments in
{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
Ok, also changed that to uidb32=uid and key=token results in a HTML page displaying "BAD TOKEN".
Now, I'm completely at a loss.
How to configure django-allauth and django-rest-auth so that I can do a rest request to send the email containing a valid URL which the user can use to change his/her password?
UPDATE: I just saw django-allauth is no longer maintained and that you should switch to: dj-rest-auth. Now the process starts all over again...
Ok, the following works, posting for reference because I have lost an awful lot of time on this.
Pipfile:
[packages]
django = "~=3.0"
django-allauth = "0.50.0"
django-rest-auth = "0.9.5"
urls.py:
from django.contrib import admin
from django.urls import path, re_path
# Register
from allauth.account.views import ConfirmEmailView
from rest_auth.registration.views import RegisterView, VerifyEmailView
# Password reset
from rest_auth.views import PasswordResetView, PasswordResetConfirmView
urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'^confirm-email/(?P<key>[-:\w]+)/$',
ConfirmEmailView.as_view(), name='account_confirm_email'),
path('user/register/',
RegisterView.as_view(),
name='rest_register'
),
path('user/verify-email/',
VerifyEmailView.as_view(),
name='rest_verify_email'
),
# Password reset
path('user/password/reset/',
PasswordResetView.as_view(),
name='rest_password_reset'
),
path('user/password/reset/confirm/<uidb64>/<token>/',
PasswordResetConfirmView.as_view(),
name='password_reset_confirm'),
]
I'm able to post to: http://127.0.0.1:8000/user/password/reset/ with a JSON payload of { "email": "test1#test.com" }.
A Email is generated with an reset URL, clicking this URL brings the user to the browsable API page of Django:
However, this page is not intended to be exposed to the user. So my next question on S.O. is: How to create a custom page for the user to reset his/her password?
I have only been able to make the following changes in django code:
settings.py:
added along with other apps added in
INSTALLED_APPS = [
.....
'django_otp',
'django_otp.plugins.otp_totp',
]
In additions to other middleware configurations, added:
MIDDLEWARE = [
'django_otp.middleware.OTPMiddleware',
]
urls.py:
from django_otp.admin import OTPAdminSite
from django_otp.plugins.otp_totp.models import TOTPDevice
admin_site = OTPAdmin(name='OTPAdmin')
admin_site.register(User)
admin_site.register(TOTPDevice)
urlpatterns = [
path('admin/', admin_site.urls), #otp app
path('dadmin/', admin.site.urls),
]
Then I ran: $ python3 manage.py migrate otp_totp --fake
and runserver. Created a user and totp device. Scanned the qr code in google authenticator. Then tried logging in using the admin url to login for this new user. It asks for the token generated which I input, it says invalid token though user is authenticated. Seen other posts where the secret code needs to be converted to 32basecode etc, but don't know exactly and where to implement. What more code needs to be added to get this working? I will require detailed code and steps for my use case where i need to change the time for generating the code and send via sms using my service provider api and redirect to password reset form.
Using django 3.1, django-otp 1.0.2
My google authenticator works with my gmail account, so there is no clock time difference either.
I set up everything as the Django documentation but when I test sending an email.It works but When I check my inbox I find out that I sent and revived from to the same email address.
Here is the settings.py
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
EMAIL_HOST = "smtp.gmail.com"
EMAIL_USE_TLS = True
EMAIL_PORT = 587
EMAIL_HOST_USER = "myemail#gmail.com"
EMAIL_HOST_PASSWORD = "mypassword"
And the views.py
...
send_mail( 'subject', 'message', 'user#gmail.com', ['myemail#gmail.com',], fail_silently=False, )
...
But I received an email from myemail#gmail.com to me(myemail#gmail.com).
Im not sure if you did this already but if youre using gmail then you will need to do the following.
Sign in to your Google Admin console (Sign in using an administrator account)
Click Security > Less secure apps.
Select Allow users to manage their access to less secure apps.
Click Save.25
Also you should use environment variables for the email address if you are live already eg:
EMAIL_HOST_USER = os.environ.get('MY_EMAIL_USER')
EMAIL_HOST_PASSWORD = os.environ.get('MY_EMAIL_PASS')
If its all working and you are just getting the mail to the wrong address can you send on the document you followed?
In terms of you settings.py that looks fine to me.
First of all, I'd just like to clarify that I've looked at all the other questions in regard to this on Stack Overflow and I haven't been able to resolve the issue.
So, the issue I'm having is that I'm not receiving a password reset email on my site, even though everything indicates that the email has been sent. I say this because I get the confirmation on my screen that the email has been sent and I also get the email displayed in the console (see below).
Here are my email settings:
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
EMAIL_USE_TLS = True
EMAIL_HOST = "localhost"
EMAIL_PORT = 25
EMAIL_HOST_USER = os.environ.get("EMAIL_ADDRESS")
EMAIL_HOST_PASSWORD = os.environ.get("EMAIL_PASSWORD")
Here are my password reset URLs:
from django.conf.urls import url
from django.core.urlresolvers import reverse_lazy
from accounts.views import change_password
from django.contrib.auth.views import (
password_reset,
password_reset_done,
password_reset_confirm,
password_reset_complete)
urlpatterns = [
url(r'^$', password_reset, name='password_reset'),
url(r'^reset-password/done/$', password_reset_done,
name='password_reset_done'),
url(r'^reset-password/confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$',
password_reset_confirm, name='password_reset_confirm'),
url(r'^complete/$', password_reset_complete,
name='password_reset_complete'),
url(r'^change-password/$', change_password, name='change_password'),
]
Any feedback is greatly appreciated!
Thanks in advance.
You specified as EMAIL_BACKEND:
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
This is a Console backend [Django-doc], so it does not send an email, but prints the email to the console. This can for example be used for testing purposes.
You can specify as backend for example the SMTP backend [Django-doc]:
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
Basically I want to developed a system where user logged in using username and password using 'JSONWebTokenAuthentication'.That's way I am use 'django rest framework JWT'.Before i was create an accounts app where user can registration and login using there username and password.
In account/urls.py
urlpatterns = [
url('^login/$', UserLoginApiView.as_view(), name='login'),
url('^register/$', UserCreateApiView.as_view(), name='register'),
]
In mainproject/urls.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api/auth/token/', obtain_jwt_token),
url(r'^api/users/', include("account.urls", namespace='user_api')),
]
When i was open 'api/auth/token/' This URL. it shows username field and password field in the browserable api it's ok coz it is built in view djangorestframework-jwt.If username & password match in db that's provided a token.
My question is when i use my own login view .If using 'djangorestframework-jwt' obtain_jwt_token views in api/auth/token/
Only registration is enough to create an user. Is any needs to create an extra login view if we use djangorestframework-jwt.
If you want to do registration using username and password just use api/auth/token to login. It gives you jwt-token which you can use to authenticate with other class and views.