Account Merging with Google Login and Normal Registration
In my Django project, I have both normal registration and Google login. If a user registers normally and provides their email, and then tries to log in with Google using the same email, the classic login screen appears. What I want is this: If a user logs in with Google first and then tries to log in with the same email via normal registration, or if they register normally and later try to log in with Google using the same email, I want both methods to lead to the same account. In other words, regardless of whether they log in with Google or normal registration, the user's information should be merged and they should access the same account in both cases.
socal login sections in settings.py:
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = '<722444511487-2i7e9u3urlugcp2cp6slp09jjg7kgdg3.apps.googleusercontent.com>'
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = '<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>'
SOCIALACCOUNT_LOGIN_ON_GET=True
ACCOUNT_UNIQUE_EMAIL = True
EMAIL_VERIFICATION_METHOD = 'email'
# settings.py
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587 # TLS GENELLİKLE 587 PORTUNU KULLANIR SSL İSE GENELLİKLE 465 PORTUNU KULLANIR
EMAIL_USE_TLS = True # TLS SSL'E GÖRE DAHA MODERN VE GÜVENLİDİR
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
views.py:
def loginUser(request):
if (request.user.is_authenticated):
messages.error(request,"Giriş Yapılıyken Giriş Yapamazsın!")
return redirect("index")
form = LoginForm(request.POST or None)
if (form.is_valid()):
login(request,form.cleaned_data["user"])
messages.success(request,"Başarıyla Giriş Yaptın!")
return redirect("index")
return render(request,"login.html",{"form":form})
def register(request):
if (request.user.is_authenticated):
messages.error(request,"Giriş Yapılıyken Kayıt Olamazsın!")
return redirect("index")
form = RegisterForm(request.POST or None)
if (form.is_valid()):
username = form.cleaned_data["username"]
password = form.cleaned_data["password"]
email = form.cleaned_data["email"]
newUser = User(username=username,email=email)
newUser.is_active = False
newUser.set_password(password)
newUser.backend = "django.contrib.auth.backends.ModelBackend"
newUser.save()
send_verification_mail(request,newUser)
newUser_profile = Profile(user=newUser,profile_photo="profile_photo/default/default.jpg")
newUser_profile.save()
messages.success(request,"Hesabınız Oluşturuldu Hesabınızı Aktif Etmek İçin Mail Kutunuzu Kontrol Edin")
return redirect("index")
return render(request,"register.html",{"form":form})
def send_verification_mail(request,user):
current_site = get_current_site(request) # Bu sitenin bilgilerini alır
subject = "Email Dogrulama"
message = render_to_string("email/email_verification.html",{ # render_to_string, bir Django şablonunu işleyip dönen sonucu bir string (metin) olarak döndürür./NORMAL RENDER İSE, bir Django şablonunu işleyip bir HttpResponse nesnesi döndürür. Bu, işlenmiş şablonu bir HTTP yanıtı olarak tarayıcıya göndermek için kullanılır.
'user': user,
'domain': current_site.domain, # Yukarıda aldığımız bu sitenin domaini
'uid': urlsafe_base64_encode(force_bytes(int(user.pk))), # user objesinin id'sini byte veri tipine çevirip url için güvenli ve uygun olarak base64 olarak tekrar kodlar
'token': default_token_generator.make_token(user), # user objesine özel token oluşturur
})
email = EmailMessage(
subject=subject,
body=message,
from_email="sefasteam435@gmail.com",
to=[user.email],
)
email.content_subtype = "html" # Email içeriğinin türünü html yaptık
email.send(fail_silently=False)
def verify_email(request, uidb64, token):
try:
uid = urlsafe_base64_decode(uidb64).decode()
user = get_object_or_404(User, pk=uid)
except (TypeError, ValueError, OverflowError, User.DoesNotExist) as e:
user = None
if user and default_token_generator.check_token(user, token):
user.is_active = True
user.save()
messages.success(request, 'E-posta doğrulamanız başarılı. Artık giriş yapabilirsiniz.')
return redirect('user:login')
else:
messages.error(request, 'Geçersiz doğrulama bağlantısı.')
return redirect('user:register')
I couldn't do anything for myself, I researched it, but I couldn't find what I was looking for.
Note : I'm new to StackOverflow, please forgive me if I made any mistake while asking my question.
Try to login user with google and look he has an email or this field is empty (user.email)?
And hide your secret keys, like this:
project tree
root
--config
----settings.py
.env
first you need pip install python-dotenv
root/config/settings.py
import os
from dotenv import load_dotenv
load_dotenv()
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = os.environ.get("GOOGLE_KEY")
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = os.environ.get("GOOGLE_SECRET")
.env it's file name is required, you can put it in root dir or other place you like (in .env not necessary to put quotation marks like GOOGLE_KEY="YOUR_KEY")
.env
GOOGLE_KEY=YOUR_KEY
GOOGLE_SECRET=YOUR_SECRET