Skip to content

Commit

Permalink
Merge pull request #69 from HungrySlugs-CSE115A/login
Browse files Browse the repository at this point in the history
Login
  • Loading branch information
anyazhang17 authored May 10, 2024
2 parents 2dcbd85 + e07a809 commit 0dcbff1
Show file tree
Hide file tree
Showing 13 changed files with 262 additions and 60 deletions.
5 changes: 5 additions & 0 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Metadata } from "next";
import { Montserrat } from "next/font/google";
import "./globals.css";
//import Link from "next/link";

import Navbar from "@/components/navbar";
import Testbar from "@/components/testbar";
Expand All @@ -12,6 +13,8 @@ export const metadata: Metadata = {
description: "Generated by create next app",
};



// This is the height of the navbar which will also be used to set the padding-top of the main content
// NOTE: you should modify this value to match the height of the navbar
const navbarHeight: string = "60px";
Expand All @@ -29,7 +32,9 @@ export default function RootLayout({

{children}
</div>

</body>

</html>
);
}
82 changes: 82 additions & 0 deletions app/loginPage/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
"use client";
import { useEffect, useState } from "react";
import { GoogleOAuthProvider, useGoogleLogin, googleLogout, TokenResponse} from "@react-oauth/google";
import { jwtDecode } from "jwt-decode";
import axios from "axios";

interface User {
name: string;
email: string;
picture: string;
}
const LoginPage = () => {
return(
<GoogleOAuthProvider clientId={'1040494859138-vji3ddfil5jancg23ifaginvmn71hktf.apps.googleusercontent.com'}>
<LoginComponent/>
</GoogleOAuthProvider>
)
}

const LoginComponent = () => {
const [user, setUser] = useState<User | null>(null);



useEffect(() => {
console.log("LoginPage component mounted");
}, []);

const handleLoginSuccess = (tokenResponse: any) => {
if ('code' in tokenResponse) {
// Handle authorization code flow
console.log('Authorization Code:', tokenResponse.code);
// Exchange code for tokens here
} else {
// Handle implicit flow
console.log('Token Received:', tokenResponse.access_token);
const decoded: User = jwtDecode(tokenResponse.id_token);
setUser({
name: decoded.name,
email: decoded.email,
picture: decoded.picture
});
// Send token to backend if necessary
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));
}

};
const login = useGoogleLogin({
flow: "auth-code",

onSuccess: (tokenResponse) => handleLoginSuccess,
onError: (errorResponse) => console.error('Login Failed', errorResponse),
});
const handleLogout = () => {
googleLogout();
setUser(null); // Clears the user state, effectively logging out the user
console.log('Logged out successfully');
};
return (
<div>
<button onClick={() => login()} className="hover:underline decoration-yellow-400 underline-offset-8 m-5 p-2 text-[#003C6C] font-medium text-xl">
Login with Google
</button>
{user && (
<div>
<img src={user.picture} alt="User profile" />
<h2>Welcome, {user.name} - {user.email}</h2>

</div>
)}
<button onClick={handleLogout} className="hover:underline decoration-yellow-400 underline-offset-8 top-0 right-0 m-5 p-2 text-[#003C6C] font-medium text-xl">
Logout
</button>
</div>

);
};

export default LoginPage;

61 changes: 4 additions & 57 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,6 @@
import { useState, useEffect } from "react";
import axios from "axios";
import Link from "next/link";
import {
GoogleOAuthProvider,
GoogleLogin,
googleLogout,
} from "@react-oauth/google";
import { jwtDecode } from "jwt-decode";

interface Food {
name: string;
Expand All @@ -20,6 +14,7 @@ interface subCategory {
}

interface Category {
forEach(arg0: (category: any) => void): unknown;
name: string;
sub_categories: Array<subCategory>;
}
Expand Down Expand Up @@ -51,7 +46,7 @@ function ButtonLink(props: any) {
);
}

function Home() {
export default function Home() {
const [dhs, setDhs] = useState<DiningHall[]>([]);
const [dhs_names, set_dhs_names] = useState([""]);
const [searchInput, setSearchInput] = useState("");
Expand Down Expand Up @@ -84,7 +79,7 @@ function Home() {
const allFoods: { food: Food; dhName: string; categoryName: string }[] = [];
dhs.forEach((dh) => {
dh.categories.forEach((category) => {
category.sub_categories.forEach((subCategory) => {
category.sub_categories.forEach((subCategory: { foods: any[]; }) => {
subCategory.foods.forEach((food) => {
allFoods.push({
food,
Expand Down Expand Up @@ -159,55 +154,7 @@ function Home() {
</h3>

</div>
{/* Account Button */}
</main>
);
}

export default function Page() {
const [user, setUser] = useState<User | null>(null);

useEffect(() => {
console.log(
"Page component loaded and GoogleOAuthProvider should be active",
);
}, []);

const handleLogout = () => {
googleLogout();
setUser(null); // Clear user state on logout
console.log("Logout Successful");
};

const handleLoginSuccess = (credentialResponse: any) => {
console.log("Login Successful", credentialResponse);
const decoded: User = jwtDecode(credentialResponse.credential);
setUser({
name: decoded.name,
picture: decoded.picture,
});
};

return (
<GoogleOAuthProvider clientId="1040494859138-vji3ddfil5jancg23ifaginvmn71hktf.apps.googleusercontent.com">
<Home />
<GoogleLogin
onSuccess={handleLoginSuccess}
onError={() => {
console.log("Login Failed");
}}
/>
{user && (
<div>
<img src={user.picture} alt="User profile" />
<h2>{user.name}</h2>
</div>
)}
<button
onClick={handleLogout}
className="p-2 mt-2 text-white bg-red-600 rounded"
>
Logout
</button>
</GoogleOAuthProvider>
);
}
39 changes: 39 additions & 0 deletions backend/backend/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@
"corsheaders",
"rest_framework",
"myapi",
'oauth2_provider',
'drf_social_oauth2',
'social_django',
]

MIDDLEWARE = [
Expand All @@ -55,6 +58,7 @@
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"corsheaders.middleware.CorsMiddleware",
'social_django.middleware.SocialAuthExceptionMiddleware',
]

CORS_ORIGIN_ALLOW_ALL = True
Expand All @@ -72,6 +76,8 @@
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
'social_django.context_processors.backends',
'social_django.context_processors.login_redirect',
],
},
},
Expand Down Expand Up @@ -131,3 +137,36 @@
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

LOGIN_URL = '/admin/login/'

REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
'drf_social_oauth2.authentication.SocialAuthentication',
),
}

AUTHENTICATION_BACKENDS = (
'social_core.backends.google.GoogleOAuth2',
'django.contrib.auth.backends.ModelBackend',
'drf_social_oauth2.backends.DjangoOAuth2',
)
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = '1040494859138-vji3ddfil5jancg23ifaginvmn71hktf.apps.googleusercontent.com'
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = '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'

SOCIAL_AUTH_GOOGLE_OAUTH2_SCOPE = [
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/userinfo.profile',
]

SOCIAL_AUTH_PIPELINE = (
'social_core.pipeline.social_auth.social_details',
'social_core.pipeline.social_auth.social_uid',
'social_core.pipeline.social_auth.auth_allowed',
'social_core.pipeline.social_auth.social_user',
'social_core.pipeline.user.create_user',
'social_core.pipeline.social_auth.associate_user',
'social_core.pipeline.social_auth.load_extra_data',
'social_core.pipeline.user.user_details',
)
4 changes: 4 additions & 0 deletions backend/backend/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,8 @@
path("admin/", admin.site.urls),
# For the api
path("myapi/", include("myapi.urls")),
path('o/', include('oauth2_provider.urls', namespace='oauth2_provider')),
path('auth/',include('drf_social_oauth2.urls',namespace='drf')),
path('social-auth/', include('social_django.urls', namespace='social')),

]
41 changes: 41 additions & 0 deletions backend/myapi/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Generated by Django 5.0.4 on 2024-05-07 04:49

import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

initial = True

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.CreateModel(
name="UserProfile",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("first_name", models.CharField(blank=True, max_length=50)),
("last_name", models.CharField(blank=True, max_length=50)),
("email", models.EmailField(blank=True, max_length=254)),
(
"user",
models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL,
),
),
],
),
]
18 changes: 18 additions & 0 deletions backend/myapi/migrations/0002_alter_userprofile_email.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.0.4 on 2024-05-07 19:26

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("myapi", "0001_initial"),
]

operations = [
migrations.AlterField(
model_name="userprofile",
name="email",
field=models.EmailField(max_length=254, unique=True),
),
]
16 changes: 16 additions & 0 deletions backend/myapi/migrations/0003_delete_userprofile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Generated by Django 5.0.4 on 2024-05-08 04:25

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
("myapi", "0002_alter_userprofile_email"),
]

operations = [
migrations.DeleteModel(
name="UserProfile",
),
]
2 changes: 1 addition & 1 deletion backend/myapi/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.db import models
from db_connection import db

from django.contrib.auth.models import User
# Create your models here.

# locations Model
Expand Down
5 changes: 4 additions & 1 deletion backend/myapi/urls.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from django.urls import path
from django.urls import path, re_path
from . import views

urlpatterns = [
path("hello-world/", views.hello_world, name="hello_world"),
path("locations/", views.get_locations, name="locations"),
#path('users/', views.create_user, name='create_user'),
path('users/<str:backend>/', views.create_user, name='create_user'),
#path('getuser/', views.get_user, name='get_user'),
]
Loading

0 comments on commit 0dcbff1

Please sign in to comment.