Регистрация в Google, jwt остается в системе
Я только что добавил возможность регистрации через Google. В целях безопасности я добавил поле в db, которое является ложным, если пользователь зарегистрирован обычным способом (Username & PW) и истинным, если он зарегистрирован в google.
class CustomUser(AbstractUser):
objects = UserManager()
REQUIRED_FIELDS = []
USERNAME_FIELD = 'email'
username = models.CharField(max_length=40, unique=False,null=True, blank=True)
email = models.EmailField(_('email address'), unique=True)
profile_image = models.ImageField(null=True,blank=True,default = "users.png",upload_to='',)
created = models.DateTimeField(auto_now_add=True)
id = models.UUIDField(default=uuid.uuid4, unique=True,primary_key=True, editable=False)
telephone = models.CharField(blank=True, max_length=20, null=True)
email_is_verified = models.BooleanField(default = False, null=False, blank = False)
currentVerificationToken = models.CharField(max_length = 6, default="000000")
withGoogleRegistered = models.BooleanField(default = False)
def __str__(self):
return self.email
Итак, если вы пытаетесь войти в систему обычным способом, но адрес электронной почты привязан к учетной записи, зарегистрированной в google, вы не сможете этого сделать. Если вы попытаетесь войти с адресом электронной почты, связанным обычным способом, но он связан с учетной записью, связанной с google, вы не сможете этого сделать. Итак, я сделал это, чтобы разделить учетные записи с паролем и учетные записи без пароля... Но теперь возникла небольшая проблема. Чтобы получить токен обновления (JWT), я должен указать имя пользователя и пароль, иначе я не смогу его получить...
function fetchToken() {
if (user && !Object.hasOwn(user, "fromBackend")) {
fetch("http://127.0.0.1:8000/token/", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
email: user.email,
password: user.password,
}),
})
.then((response) => response.json())
.then((data) => {
if (data.access) {
setRemoveTokens(data);
updateUser();
}
});
} else if (localStorage.getItem("refreshToken-allkids") != null) {
getNewTokens();
updateUser();
}
Для этого я использую rest_framework_simplejw
from django.contrib import admin
from django.urls import path, include
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
)
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path("user/", include("User.urls")),
path("token/", TokenObtainPairView.as_view(), name="obtain_token"),
path("token/refresh/", TokenRefreshView.as_view(), name="refresh_token"),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Итак, что было сказано, перейдем к вопросу: как я могу получить токен обновления для зарегистрированных аккаунтов Google, не имея пароля?
Вот как я создаю зарегистрированный аккаунт google:
@api_view(["POST"])
def googleRegistrationOrLogin(request):
body = request.body.decode('utf-8')
token = json.loads(body)
CLIENT_ID = "591603096190-1fv6asqdpmm6td8t66as5temri420j8b.apps.googleusercontent.com"
try:
idinfo = id_token.verify_oauth2_token(token, requests.Request(), CLIENT_ID)
except:
print("Failure")
return Response("Failure")
try:
user = CustomUser.objects.get(email = idinfo["email"])
if user.withGoogleRegistered:
login(request, user)
user = CustomUserLoggedSerializer(user, many = False)
return Response(user.data)
else:
return Response("Email already in use, please create an account the usal way.")
except:
randomEmailToken = random.randrange(100000,999999)
try:
user = CustomUser.objects.create(username = idinfo["name"],profile_image = idinfo["picture"],withGoogleRegistered = True,password="GoogleRegistered", email = idinfo["email"],currentVerificationToken=randomEmailToken, email_is_verified = True if idinfo["email_verified"] else False)
except:
return Response("Fatal Error")
user = CustomUserLoggedSerializer(user, many = False)
return Response(user.data)
Я знаю, что в настоящее время он не чист, но пока что это справедливо.