Index: backend/auth_form/adapters.py
===================================================================
--- backend/auth_form/adapters.py	(revision 74a3ebcd0dae1a0baa744b0bb598de6a6da46fda)
+++ backend/auth_form/adapters.py	(revision 74a3ebcd0dae1a0baa744b0bb598de6a6da46fda)
@@ -0,0 +1,12 @@
+from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
+
+class CustomSocialAccountAdapter(DefaultSocialAccountAdapter):
+    def populate_user(self, request, sociallogin, data):
+        user = super().populate_user(request, sociallogin, data)
+
+        first_name = data.get("first_name", "")
+        last_name = data.get("last_name", "")
+        user.first_name = first_name
+        user.last_name = last_name
+        user.full_name = f"{first_name} {last_name}".strip()
+        return user
Index: backend/auth_form/serializers.py
===================================================================
--- backend/auth_form/serializers.py	(revision 1516a98735ab8741baed2b6a5edc181448f040c0)
+++ backend/auth_form/serializers.py	(revision 74a3ebcd0dae1a0baa744b0bb598de6a6da46fda)
@@ -73,4 +73,22 @@
         else:
             raise serializers.ValidationError('Must include "email" and "password"')
+        
+class GoogleLoginSerializer(serializers.Serializer):
+    email = serializers.EmailField(required=True)
+
+    def validate(self, data):
+        try:
+            email = data.get('email')
+            User = get_user_model()
+            user = User.objects.get(email=email)
+            if user is None:
+                raise AuthenticationFailed('Invalid email or password')
+            if not user.is_active:
+                raise AuthenticationFailed('User account is disabled')
+            data['user'] = user
+            return data
+        except:
+            raise serializers.ValidationError('Must include email.')
+        
 
 class StudentFormSerializer(serializers.ModelSerializer):
Index: backend/auth_form/urls.py
===================================================================
--- backend/auth_form/urls.py	(revision 1516a98735ab8741baed2b6a5edc181448f040c0)
+++ backend/auth_form/urls.py	(revision 74a3ebcd0dae1a0baa744b0bb598de6a6da46fda)
@@ -1,4 +1,4 @@
-from django.urls import path
-from .views import RegisterView, LoginView, StudentFormView, UserDetailView, LogoutView
+from django.urls import path, include
+from .views import RegisterView, LoginView, StudentFormView, UserDetailView, LogoutView, CustomGoogleLogin
 from rest_framework_simplejwt.views import TokenObtainPairView
 from .serializers import CustomTokenObtainPairSerializer
@@ -10,5 +10,9 @@
     path('logout/', LogoutView.as_view(), name='auth_logout'),
     path('refresh/', TokenRefreshView.as_view(), name='token_refresh'),
+    path('user/', UserDetailView.as_view(), name='user_detail'),
     path('form/', StudentFormView.as_view(), name="student_form"),
-    path('user/', UserDetailView.as_view(), name='user_detail'),
+    path('google/login/', CustomGoogleLogin.as_view(), name='google_login'),
+    path('', include('dj_rest_auth.urls')),
+    path('registration/', include('dj_rest_auth.registration.urls')), 
+    path('google/', include('allauth.socialaccount.urls')), 
 ]
Index: backend/auth_form/views.py
===================================================================
--- backend/auth_form/views.py	(revision 1516a98735ab8741baed2b6a5edc181448f040c0)
+++ backend/auth_form/views.py	(revision 74a3ebcd0dae1a0baa744b0bb598de6a6da46fda)
@@ -8,5 +8,6 @@
 from rest_framework_simplejwt.tokens import RefreshToken
 from .permissions import IsStudent, CanSubmitForm, CanUpdateForm
-
+from dj_rest_auth.registration.views import SocialLoginView
+from allauth.socialaccount.providers.google.views import GoogleOAuth2Adapter
 
 
@@ -116,4 +117,16 @@
 
 
+class CustomGoogleLogin(SocialLoginView):
+    adapter_class = GoogleOAuth2Adapter
+
+    def get_response(self):
+        refresh = RefreshToken.for_user(self.user)
+
+        return Response({
+            'refresh': str(refresh),
+            'access': str(refresh.access_token),
+            'full_name': self.user.full_name,
+            'user_type': self.user.user_type,
+        }, status=status.HTTP_200_OK)
 
 
Index: backend/backend/settings.py
===================================================================
--- backend/backend/settings.py	(revision 1516a98735ab8741baed2b6a5edc181448f040c0)
+++ backend/backend/settings.py	(revision 74a3ebcd0dae1a0baa744b0bb598de6a6da46fda)
@@ -45,4 +45,12 @@
     'rest_framework_simplejwt',
     'rest_framework_simplejwt.token_blacklist',
+    'rest_framework.authtoken',
+    'dj_rest_auth',
+    'dj_rest_auth.registration',
+    'allauth',
+    'allauth.account',
+    'allauth.socialaccount',
+    'allauth.socialaccount.providers.google',
+    'django.contrib.sites',
     'auth_form',
 ]
@@ -69,4 +77,5 @@
     'corsheaders.middleware.CorsMiddleware',
     'django.middleware.common.CommonMiddleware',
+    'allauth.account.middleware.AccountMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
@@ -168,2 +177,19 @@
     'django.contrib.auth.backends.ModelBackend',  # default backend
 ]
+
+SITE_ID = 1
+
+SOCIALACCOUNT_ADAPTER = "auth_form.adapters.CustomSocialAccountAdapter"
+ACCOUNT_LOGIN_METHODS = {'email'}
+ACCOUNT_SIGNUP_FIELDS = ["email*", "password1*"]
+
+SOCIALACCOUNT_PROVIDERS = {
+    'google': {
+        'APP': {
+            'client_id': config('GOOGLE_CLIENT_ID'),
+            'secret': config('GOOGLE_CLIENT_SECRET'),
+            'key': ''
+        },
+        'SCOPE': ['profile', 'email'],
+    }
+}
Index: backend/requirements.txt
===================================================================
--- backend/requirements.txt	(revision 1516a98735ab8741baed2b6a5edc181448f040c0)
+++ backend/requirements.txt	(revision 74a3ebcd0dae1a0baa744b0bb598de6a6da46fda)
@@ -12,2 +12,5 @@
 numpy>=2.2.5
 psycopg2-binary>=2.9.10
+dj-rest-auth>=7.0.1
+django-allauth>=65.9.0
+cryptography>=45.0.4
Index: docker-compose.yml
===================================================================
--- docker-compose.yml	(revision 1516a98735ab8741baed2b6a5edc181448f040c0)
+++ docker-compose.yml	(revision 74a3ebcd0dae1a0baa744b0bb598de6a6da46fda)
@@ -31,4 +31,5 @@
       - NODE_ENV=development
       - CHOKIDAR_USEPOLLING="true"
+      - VITE_GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID}
     depends_on:
       - backend
Index: frontend/package-lock.json
===================================================================
--- frontend/package-lock.json	(revision 1516a98735ab8741baed2b6a5edc181448f040c0)
+++ frontend/package-lock.json	(revision 74a3ebcd0dae1a0baa744b0bb598de6a6da46fda)
@@ -9,4 +9,5 @@
 			"version": "0.0.0",
 			"dependencies": {
+				"@react-oauth/google": "^0.12.2",
 				"axios": "^1.9.0",
 				"jwt-decode": "^4.0.0",
@@ -1116,4 +1117,14 @@
 			"engines": {
 				"node": ">=14"
+			}
+		},
+		"node_modules/@react-oauth/google": {
+			"version": "0.12.2",
+			"resolved": "https://registry.npmjs.org/@react-oauth/google/-/google-0.12.2.tgz",
+			"integrity": "sha512-d1GVm2uD4E44EJft2RbKtp8Z1fp/gK8Lb6KHgs3pHlM0PxCXGLaq8LLYQYENnN4xPWO1gkL4apBtlPKzpLvZwg==",
+			"license": "MIT",
+			"peerDependencies": {
+				"react": ">=16.8.0",
+				"react-dom": ">=16.8.0"
 			}
 		},
Index: frontend/package.json
===================================================================
--- frontend/package.json	(revision 1516a98735ab8741baed2b6a5edc181448f040c0)
+++ frontend/package.json	(revision 74a3ebcd0dae1a0baa744b0bb598de6a6da46fda)
@@ -14,4 +14,5 @@
 	},
 	"dependencies": {
+		"@react-oauth/google": "^0.12.2",
 		"axios": "^1.9.0",
 		"jwt-decode": "^4.0.0",
Index: frontend/src/components/Navbar.tsx
===================================================================
--- frontend/src/components/Navbar.tsx	(revision 1516a98735ab8741baed2b6a5edc181448f040c0)
+++ frontend/src/components/Navbar.tsx	(revision 74a3ebcd0dae1a0baa744b0bb598de6a6da46fda)
@@ -1,2 +1,4 @@
+import { useGoogleLogin } from "@react-oauth/google";
+import axios from "axios";
 import { useEffect, useRef, useState } from "react";
 import { Link, useNavigate } from "react-router-dom";
@@ -11,4 +13,5 @@
 	const [profileMenuOpen, setProfileMenuOpen] = useState(false);
 	const [, setRecommendations] = useRecommendations();
+	const { login } = useAuth();
 	const { isAuthenticated, logout, user } = useAuth();
 	const { setFavoriteIds, setLikedIds, setDislikedIds } = usePreferences();
@@ -41,4 +44,30 @@
 		toast.success("Успешно сте одјавени!");
 	};
+
+	const googleLogin = useGoogleLogin({
+		onSuccess: async (tokenResponse) => {
+			const accessToken = tokenResponse.access_token;
+			try {
+				const response = await axios.post<{
+					access: string;
+					refresh: string;
+					full_name: string;
+					user_type: string;
+				}>("http://localhost:8000/auth/google/login/", {
+					access_token: accessToken,
+				});
+				const { access, refresh, full_name, user_type } = response.data;
+				login(access, refresh, { full_name, user_type });
+				navigate("/");
+				toast.success("Успешно сте најавени!");
+			} catch (err: any) {
+				console.error("Login failed:", err.response?.data || err.message);
+			}
+		},
+		onError: () => {
+			console.error("Login Failed");
+		},
+		flow: "implicit",
+	});
 
 	// const testAccountLogin = async () => {
@@ -157,4 +186,7 @@
 					)}
 				</div>
+				<div>
+					<button onClick={() => googleLogin()}>Login with google</button>
+				</div>
 			</div>
 
Index: frontend/src/main.tsx
===================================================================
--- frontend/src/main.tsx	(revision 1516a98735ab8741baed2b6a5edc181448f040c0)
+++ frontend/src/main.tsx	(revision 74a3ebcd0dae1a0baa744b0bb598de6a6da46fda)
@@ -1,2 +1,3 @@
+import { GoogleOAuthProvider } from "@react-oauth/google";
 import { StrictMode } from "react";
 import { createRoot } from "react-dom/client";
@@ -10,13 +11,15 @@
 createRoot(document.getElementById("root")!).render(
 	<StrictMode>
-		<AuthProvider>
-			<SubjectsProvider>
-				<RecommendationsProvider>
-					<PreferencesProvider>
-						<App />
-					</PreferencesProvider>
-				</RecommendationsProvider>
-			</SubjectsProvider>
-		</AuthProvider>
+		<GoogleOAuthProvider clientId={import.meta.env.VITE_GOOGLE_CLIENT_ID}>
+			<AuthProvider>
+				<SubjectsProvider>
+					<RecommendationsProvider>
+						<PreferencesProvider>
+							<App />
+						</PreferencesProvider>
+					</RecommendationsProvider>
+				</SubjectsProvider>
+			</AuthProvider>
+		</GoogleOAuthProvider>
 	</StrictMode>
 );
Index: frontend/src/vite-env.d.ts
===================================================================
--- frontend/src/vite-env.d.ts	(revision 1516a98735ab8741baed2b6a5edc181448f040c0)
+++ frontend/src/vite-env.d.ts	(revision 74a3ebcd0dae1a0baa744b0bb598de6a6da46fda)
@@ -1,1 +1,9 @@
 /// <reference types="vite/client" />
+
+interface ImportMetaEnv {
+  readonly VITE_GOOGLE_CLIENT_ID: string
+}
+
+interface ImportMeta {
+  readonly env: ImportMetaEnv
+}
