From 189f9fb02e59912ac1d42175ba7b3ced703d8216 Mon Sep 17 00:00:00 2001 From: AkhilS2 <55607137+AkhilS2@users.noreply.github.com> Date: Sat, 11 May 2024 16:26:44 -0700 Subject: [PATCH] frontend update backend token verification --- .gitignore | 1 + app/loginPage/page.tsx | 64 ++++++++++++++++++++++++++++++++++-------- backend/myapi/urls.py | 1 + backend/myapi/views.py | 54 +++++++++++++++++++++++++++++++++++ 4 files changed, 109 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 2879fed..6ec9ded 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ yarn-debug.log* yarn-error.log* # local env files +.env .env*.local # vercel diff --git a/app/loginPage/page.tsx b/app/loginPage/page.tsx index 1041c06..20da42f 100644 --- a/app/loginPage/page.tsx +++ b/app/loginPage/page.tsx @@ -4,6 +4,7 @@ import { GoogleOAuthProvider, useGoogleLogin, googleLogout, TokenResponse} from import { jwtDecode } from "jwt-decode"; import axios from "axios"; +const GOOGLE_CLIENT_ID = process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID; interface User { name: string; @@ -12,7 +13,7 @@ interface User { } const LoginPage = () => { return( - + ) @@ -21,14 +22,15 @@ const LoginPage = () => { const LoginComponent = () => { const [user, setUser] = useState(null); + useEffect(() => { console.log("LoginPage component mounted"); }, []); - const handleLoginSuccess = (tokenResponse: any) => { - if ('code' in tokenResponse) { + /*const handleLoginSuccess = async (tokenResponse: any) => { + if ('code' in tokenResponse) { // Handle authorization code flow console.log('Authorization Code:', tokenResponse.code); // Exchange code for tokens here @@ -41,19 +43,56 @@ const LoginComponent = () => { email: decoded.email, picture: decoded.picture }); - // Send token to backend if necessary + + console.log(tokenResponse); axios.post('http://localhost:8000/myapi/users/google-oauth2/', { token: tokenResponse.access_token }) .then(res => console.log('Backend login successful', res)) .catch(err => console.error('Backend login failed', err)); - } + }*/ + /*console.log(tokenResponse); + const decoded: User = jwtDecode(tokenResponse.id_token); - }; + setUser({ + name: decoded.name, + email: decoded.email, + picture: decoded.picture + })*/ + // fetching userinfo can be done on the client or the server + + + + const login = useGoogleLogin({ - flow: "auth-code", + flow: "implicit", + + onSuccess: async tokenResponse => { + console.log(tokenResponse); + //handleLoginSuccess + //client side authentication retrieve user info from access token + const userInfo = await axios + .get('https://www.googleapis.com/oauth2/v3/userinfo', { + headers: { Authorization: `Bearer ${tokenResponse.}` }, + }) + + .then(res => res.data); + //frontend user info + setUser({ + name: userInfo.name, + email: userInfo.email, + picture: userInfo.picture + }) + //send the token to backend + axios.post('http://localhost:8000/myapi/users/', {tokenResponse: tokenResponse}) + .then(res => console.log('Backend login successful', res)) + .catch(err => console.error('Backend login failed', err)) + + - onSuccess: (tokenResponse) => handleLoginSuccess, + + }, onError: (errorResponse) => console.error('Login Failed', errorResponse), }); + const handleLogout = () => { googleLogout(); setUser(null); // Clears the user state, effectively logging out the user @@ -66,9 +105,11 @@ const LoginComponent = () => { {user && (
- User profile -

Welcome, {user.name} - {user.email}

- +
+ User profile +
+

Welcome, {user.name}

+

Email: {user.email}

)} + ); }; diff --git a/backend/myapi/urls.py b/backend/myapi/urls.py index 0e34851..ff61ec0 100644 --- a/backend/myapi/urls.py +++ b/backend/myapi/urls.py @@ -4,4 +4,5 @@ urlpatterns = [ path("hello-world/", views.hello_world, name="hello_world"), path("locations/", views.get_locations, name="locations"), + path("users/", views.validate_user, name="users") ] diff --git a/backend/myapi/views.py b/backend/myapi/views.py index 9575c9a..0022f46 100644 --- a/backend/myapi/views.py +++ b/backend/myapi/views.py @@ -1,6 +1,16 @@ from django.conf.locale import fr from rest_framework.response import Response from rest_framework.decorators import api_view +from django.conf import settings +from django.http import JsonResponse +from rest_framework.decorators import api_view +from rest_framework.exceptions import ValidationError +import requests + + + +GOOGLE_ID_TOKEN_INFO_URL = 'https://www.googleapis.com/oauth2/v3/tokeninfo' +GOOGLE_USER_INFO_URL = 'https://www.googleapis.com/oauth2/v3/userinfo' from .db_functions.locations import ( get_all_locations_from_db, @@ -59,3 +69,47 @@ def get_locations(request): json_data = {"locations": locations} return Response(json_data) + +@api_view(["POST"]) +def validate_user(request): + token_response = request.data.get('tokenResponse') + access_token = token_response.get('access_token') + id_token = token_response.get('code') + print(id_token) + try: + response = requests.get( + GOOGLE_ID_TOKEN_INFO_URL, + params={'id_token': id_token} + ) + except: + return JsonResponse({'error': 'Failed to validate id token token'}, status=500) + + + + #using access token we can get the user information + + try: + response = requests.get( + GOOGLE_USER_INFO_URL, + headers={'Authorization': f'Bearer {access_token}'} + ) + response.raise_for_status() + user_info = response.json() + print(user_info["email"]) + #add user_info to database using get or create possibly + #print(user_info) + + + except requests.RequestException as e: + return JsonResponse({'error': 'Failed to validate access token'}, status=500) + + return JsonResponse({'message': 'User is validated', 'user_info': user_info}) + + + + + + + + +