Django social allauth with JWT token - django

I made registration via social networks using the allauth library.
Added the necessary settings:
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_AUTHENTICATION_METHOD = "email".
and applications:
"allauth", #registration
"allauth.account", # registration
"allauth.socialaccount", # registration
"allauth.socialaccount.providers.vk", # registration via VK.
and in urls.py I also wrote:
url(r"^accounts/", include("allauth.urls"))
The problem is that sometimes the provider after registration may not provide an email.
And my users are identified using mail.
Signup:
I want the user to be redirected to a page with an email entry and send a confirmation link to this email after the suppliers confirm the entered data is correct.
Signin:
I want to return the JWT token to the user after confirming the providers that the entered data is correct
How to implement a signin/signup system in Django DRF JWT with allauth library?
(apparently I need to write custom views, but I tried - unsuccessfully)

Related

Account Inactive Page Not Working in django-allauth

I have successfully setup an authentication system with django application using the popular django-allauth package. I suspended a registered user by updating SuspendedUser.is_active=False but whenever I try to login as the suspended user I'd get the failed authentication message The username and/or password you specified are not correct..
Do I need any special configuration to display the account_inactive.html template as I cannot find anything that mentions that in the official documentation?.
Note: django-allauth version is 0.49.0 and django version is 4.0.3
You can override log-in function of django-allauth. And you can create a dield under your user model names is_suspended instead of giving is_active=False. And in login function before login() put an if statement.
#in django-allauth login function
if request.user.is_suspended:
message(request,'You have suspended! Cannot login!')
return
render(request, 'user/user_policy.html' {'message':message})
or search django-alluth signals
#in User model:
class User(models.Model):
...
...
...
is_suspended = models.BooleanField(default=False)
After reviewing my configurations, I realized I was using a custom authentication backend in my settings.py file. django-allauth requires allauth.account.auth_backends.AuthenticationBackend to handle authentication and permissions.
Adding this to my project config solved the problem
AUTHENTICATION_BACKENDS = [
# Needed to login by username in Django admin, regardless of `allauth`
'django.contrib.auth.backends.ModelBackend',
# `allauth` specific authentication methods, such as login by e-mail
'allauth.account.auth_backends.AuthenticationBackend',
]
Although it was stated in the docs

Django all-auth - Social login - Facebook - Pass without requesting email

So I must be missing something, I've looked for similiar questions and tried their solutions like overhere (Django allauth, require email verification for regular accounts but not for social accounts)
I would like to let users interact with my webapp without requesting their e-mailadres after logging in with their social account, in this case with their facebook account.
I have the following set up;
settings.py
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_EMAIL_VERIFICATION = 'optional'
SOCIALACCOUNT_EMAIL_REQUIRED = False
SOCIALACCOUNT_EMAIL_VERIFICATION = 'optional'
At the moment, whenever someone tries to login with their facebook account, they get redirected to the signup form requesting for their email address.
Even though I'm using email as a authentication method for regular signups, this should not be necessary for social signups am I right?
Edit:
So I tried implementing Google as a social login provider, since google has a flag for email_verified I thought this might solve the problem.
Even though you can nog login with your Google account, the social login redirects to
/accounts/social/signup/
Not really sure why but I would like to skip this step for social logins.
Kevin
Allright, found something over here Paypal redirects to /accounts/social/signup
When using a social login while the email address is already in use, the signup form kicks and you have to submit your email address.
After signup, a message will be displayed saying the email address is already in use.

django-rest-auth - Facebook social login raises unique constraint violation for existing email

I implemented registration and login with django-allauth and django-rest-auth. I can successfully login with Facebook to the server with both allauth and rest-auth (web and mobile).
When I'm trying to login with FB account that its email already exists (someone already signed up with that email), it shows the signup form. However, when I'm trying doing the same using rest-auth, I get an error:
Internal Server Error: /rest-auth/facebook/
IntegrityError at /rest-auth/facebook/
duplicate key value violates unique constraint "auth_user_username_key"
DETAIL: Key (username)=() already exists.
My Configuration:
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_EMAIL_VERIFICATION = 'optional'
SOCIALACCOUNT_AUTO_SIGNUP = True
SOCIALACCOUNT_EMAIL_VERIFICATION = False
SOCIALACCOUNT_EMAIL_REQUIRED = True
SOCIALACCOUNT_QUERY_EMAIL = True
I solved the issue by creating a social adapter that connects the existing account to the social account.
Please make sure you're aware of the risks before using it - if the email address is not verified in one of the accounts a malicious user might take control of the account by signing up before the social signup (for example).
class MySocialAccountAdapter(DefaultSocialAccountAdapter):
def pre_social_login(self, request, sociallogin):
user = sociallogin.user
if user.id:
return
if not user.email:
return
try:
user = User.objects.get(email=user.email) # if user exists, connect the account to the existing account and login
sociallogin.connect(request, user)
except User.DoesNotExist:
pass
except Exception as e:
logger.exception('Social adapter failure - {}'.format(e))
You need to set the path to the adapter in the settings.py:
SOCIALACCOUNT_ADAPTER = 'path.to.MySocialAccountAdapter'
The latest version of django-rest-auth v0.9.3 now includes social connect views, which allow you to link existing account to a social account.
In order to use them you need to be authenticated via existing account, due to security issues outlined in the previous answer. More info in the docs: Additional Social Connect Views
Unique constraint 500 error is fixed as well.

How to set password in user table when user is signup using google or facebook django allauth

By overriding the SocialAccountManager
def save_user(self, request, sociallogin, form=None):
"""
Saves a newly signed up social login. In case of auto-signup,
the signup form is not available.
"""
u = sociallogin.user
u.set_unusable_password()
if form:
get_account_adapter().save_user(request, u, form)
else:
get_account_adapter().populate_username(request, u)
sociallogin.save(request)
return u
how to get the password from social account signup
Actually, you can't.
Django Allauth does not hash or store passwords for social login users. It does not handle the authentication on its end.
Suppose a user try to do a google login at your website, the authentication happens on google servers not on your end. If the user's password is correct then LOGIN_REDIRECT_URL = "url-name/" defined in your django project redirects that user to the url.
You can't get the password. If you can, or those social apps share the password of their users, then both you and that social apps have violate the user privacy rules. In my opinion it's a crime.
The only way you could do is ask your user to set a new password for your site. Send them an email to confirm the change. But that means you have to make an additional route for your app, which has no point.

django allauth facebook social login callback failure

I configured my facebook app for social login Client OAuth Settings as
and I saved. My app is currently live but I did not submit "Submit Items for Approval" though.
Valid OAuth redirect URIs = http://www.jeviz.com/
1-User clicks following URL for sign up
http://www.jeviz.com/accounts/facebook/login/?process=login
2-User go to facebook click OK
https://www.facebook.com/dialog/oauth?redirect_uri=http%3A%2F%2Fwww.jeviz.com%2Faccounts%2Ffacebook%2Flogin%2Fcallback%2F&state=SXmYnAEwS21Z&scope=email&client_id=688227877985116&response_type=code
3-Then redirect URL leads to:
http://www.jeviz.com/accounts/facebook/login/callback/?code=AQCUL6tqM7f0jDHp_5fKgVRTtiAzYV_2MAU53VRNN8PGvtRetCbCIqXG3JXrf_tr4xYtqlDVlYFgz8aZSzYmNDdd50ZxqkWEj2m78mpmlJe-7ix47oxH8m3DW0ZUC0EAbqIt_Nz3fzHDbs0o_3NcilGZYRy5-I90W3m7UUnR68_dRpfr829snFbYELV6ifjSAOOKWj4mYIiEwXsnrdVUTdebiqBMLBssf3UUuBh1ta-gNzZyTKuFjfvwr_TVL4ykd8OCJ5lBUCUV8QrCZoptex9OJDHWL7RAKCANj976Ua3tsL3KN89hhK1S0EWV9qrvkB5qCeqinAJYParSq1ilB6Pq&state=SXmYnAEwS21Z#_=_
and gave me
502 Bad Gateway
as you see redirect url is not www.jeviz.com as suggested in the official documentdjango-allauth providers
At the end a user is created but not logged in. But If you user try to login manually by clicking social Facebook button she could login. As I stated above first signup redirect callback was wrong and user was not logged in for the first time.
What am I doing wrong?
My configuration
LOGIN_REDIRECT_URL = reverse_lazy('amazon_advertising:home')
LOGIN_URL = reverse_lazy('account_login')
LOGOUT_URL = reverse_lazy('account_logout')
ACCOUNT_AUTHENTICATION_METHOD = "username_email"
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS = 7
ACCOUNT_EMAIL_VERIFICATION = "optional"
OK, I found it. When I first add facebook as Social applications in django allauth my facebook redirect URL was /accounts/facebook/login/?process=login . I have changed it to www.jeviz.com later. I deleted facebook social app and re-created it now it works when signup! It redirect to my homepage.