mirror of
https://github.com/TurTaskProject/TurTaskWeb.git
synced 2025-12-19 05:54:07 +01:00
Fix 400 google OAuth api call
This commit is contained in:
parent
1b3fedea36
commit
4203cf517a
@ -83,10 +83,18 @@ SOCIALACCOUNT_PROVIDERS = {
|
|||||||
'client_id': config('GOOGLE_CLIENT_ID'),
|
'client_id': config('GOOGLE_CLIENT_ID'),
|
||||||
'secret': config('GOOGLE_CLIENT_SECRET'),
|
'secret': config('GOOGLE_CLIENT_SECRET'),
|
||||||
'key': ''
|
'key': ''
|
||||||
|
},
|
||||||
|
"SCOPE": [
|
||||||
|
"profile",
|
||||||
|
"email",
|
||||||
|
],
|
||||||
|
"AUTH_PARAMS": {
|
||||||
|
"access_type": "online",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CORS_ALLOW_CREDENTIALS = True
|
CORS_ALLOW_CREDENTIALS = True
|
||||||
CORS_ALLOW_ALL_ORIGINS = False
|
CORS_ALLOW_ALL_ORIGINS = False
|
||||||
CORS_ALLOWED_ORIGINS = [
|
CORS_ALLOWED_ORIGINS = [
|
||||||
@ -95,6 +103,10 @@ CORS_ALLOWED_ORIGINS = [
|
|||||||
"http://localhost:5173",
|
"http://localhost:5173",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
CSRF_TRUSTED_ORIGINS = ["http://*"]
|
||||||
|
|
||||||
|
CORS_ORIGIN_WHITELIST = ["*"]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
'corsheaders.middleware.CorsMiddleware',
|
'corsheaders.middleware.CorsMiddleware',
|
||||||
'django.middleware.security.SecurityMiddleware',
|
'django.middleware.security.SecurityMiddleware',
|
||||||
@ -104,7 +116,7 @@ MIDDLEWARE = [
|
|||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
"allauth.account.middleware.AccountMiddleware",
|
# "allauth.account.middleware.AccountMiddleware",
|
||||||
]
|
]
|
||||||
|
|
||||||
ROOT_URLCONF = 'core.urls'
|
ROOT_URLCONF = 'core.urls'
|
||||||
@ -196,3 +208,5 @@ LOGIN_REDIRECT_URL = '/'
|
|||||||
LOGOUT_REDIRECT_URL = '/'
|
LOGOUT_REDIRECT_URL = '/'
|
||||||
|
|
||||||
AUTH_USER_MODEL = "users.CustomUser"
|
AUTH_USER_MODEL = "users.CustomUser"
|
||||||
|
|
||||||
|
ACCOUNT_EMAIL_REQUIRED = True
|
||||||
23
backend/users/adapter.py
Normal file
23
backend/users/adapter.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
from allauth.socialaccount.providers.google.views import GoogleOAuth2Adapter
|
||||||
|
from allauth.socialaccount.providers.oauth2.client import OAuth2Error
|
||||||
|
import jwt
|
||||||
|
|
||||||
|
|
||||||
|
class CustomGoogleOAuth2Adapter(GoogleOAuth2Adapter):
|
||||||
|
def complete_login(self, request, app, token, response, **kwargs):
|
||||||
|
try:
|
||||||
|
identity_data = jwt.decode(
|
||||||
|
response["id_token"], #another nested id_token was returned
|
||||||
|
options={
|
||||||
|
"verify_signature": False,
|
||||||
|
"verify_iss": True,
|
||||||
|
"verify_aud": True,
|
||||||
|
"verify_exp": True,
|
||||||
|
},
|
||||||
|
issuer=self.id_token_issuer,
|
||||||
|
audience=app.client_id,
|
||||||
|
)
|
||||||
|
except jwt.PyJWTError as e:
|
||||||
|
raise OAuth2Error("Invalid id_token") from e
|
||||||
|
login = self.get_provider().sociallogin_from_response(request, identity_data)
|
||||||
|
return login
|
||||||
@ -5,10 +5,12 @@ from rest_framework import status
|
|||||||
from rest_framework.permissions import IsAuthenticated, AllowAny
|
from rest_framework.permissions import IsAuthenticated, AllowAny
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
from allauth.socialaccount.providers.google.views import GoogleOAuth2Adapter
|
|
||||||
from dj_rest_auth.registration.views import SocialLoginView
|
from dj_rest_auth.registration.views import SocialLoginView
|
||||||
|
from allauth.socialaccount.providers.oauth2.client import OAuth2Client
|
||||||
|
from .adapter import CustomGoogleOAuth2Adapter
|
||||||
from .serializers import MyTokenObtainPairSerializer, CustomUserSerializer
|
from .serializers import MyTokenObtainPairSerializer, CustomUserSerializer
|
||||||
|
|
||||||
|
from allauth.socialaccount.providers.google.views import GoogleOAuth2Adapter
|
||||||
|
|
||||||
class ObtainTokenPairWithCustomView(APIView):
|
class ObtainTokenPairWithCustomView(APIView):
|
||||||
"""
|
"""
|
||||||
@ -74,5 +76,7 @@ class GoogleLogin(SocialLoginView):
|
|||||||
Google Login View.
|
Google Login View.
|
||||||
Handles Google OAuth2 authentication.
|
Handles Google OAuth2 authentication.
|
||||||
"""
|
"""
|
||||||
permission_classes = (AllowAny,)
|
# permission_classes = (AllowAny,)
|
||||||
adapter_class = GoogleOAuth2Adapter
|
adapter_class = GoogleOAuth2Adapter
|
||||||
|
client_class = OAuth2Client
|
||||||
|
# callback_url = 'http://localhost:8000/accounts/google/login/callback/'
|
||||||
@ -16,11 +16,13 @@
|
|||||||
"@material-ui/icons": "^4.11.3",
|
"@material-ui/icons": "^4.11.3",
|
||||||
"@mui/icons-material": "^5.14.15",
|
"@mui/icons-material": "^5.14.15",
|
||||||
"@mui/material": "^5.14.15",
|
"@mui/material": "^5.14.15",
|
||||||
|
"@react-oauth/google": "^0.11.1",
|
||||||
"axios": "^1.5.1",
|
"axios": "^1.5.1",
|
||||||
"bootstrap": "^5.3.2",
|
"bootstrap": "^5.3.2",
|
||||||
"dotenv": "^16.3.1",
|
"dotenv": "^16.3.1",
|
||||||
"framer-motion": "^10.16.4",
|
"framer-motion": "^10.16.4",
|
||||||
"gapi-script": "^1.2.0",
|
"gapi-script": "^1.2.0",
|
||||||
|
"jwt-decode": "^4.0.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-bootstrap": "^2.9.1",
|
"react-bootstrap": "^2.9.1",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
|||||||
@ -23,6 +23,9 @@ dependencies:
|
|||||||
'@mui/material':
|
'@mui/material':
|
||||||
specifier: ^5.14.15
|
specifier: ^5.14.15
|
||||||
version: 5.14.15(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.33)(react-dom@18.2.0)(react@18.2.0)
|
version: 5.14.15(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.33)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@react-oauth/google':
|
||||||
|
specifier: ^0.11.1
|
||||||
|
version: 0.11.1(react-dom@18.2.0)(react@18.2.0)
|
||||||
axios:
|
axios:
|
||||||
specifier: ^1.5.1
|
specifier: ^1.5.1
|
||||||
version: 1.5.1
|
version: 1.5.1
|
||||||
@ -38,6 +41,9 @@ dependencies:
|
|||||||
gapi-script:
|
gapi-script:
|
||||||
specifier: ^1.2.0
|
specifier: ^1.2.0
|
||||||
version: 1.2.0
|
version: 1.2.0
|
||||||
|
jwt-decode:
|
||||||
|
specifier: ^4.0.0
|
||||||
|
version: 4.0.0
|
||||||
react:
|
react:
|
||||||
specifier: ^18.2.0
|
specifier: ^18.2.0
|
||||||
version: 18.2.0
|
version: 18.2.0
|
||||||
@ -1115,6 +1121,16 @@ packages:
|
|||||||
react: 18.2.0
|
react: 18.2.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@react-oauth/google@0.11.1(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-tywZisXbsdaRBVbEu0VX6dRbOSL2I6DgY97woq5NMOOOz+xtDsm418vqq+Vx10KMtra3kdHMRMf0hXLWrk2RMg==}
|
||||||
|
peerDependencies:
|
||||||
|
react: '>=16.8.0'
|
||||||
|
react-dom: '>=16.8.0'
|
||||||
|
dependencies:
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@remix-run/router@1.10.0:
|
/@remix-run/router@1.10.0:
|
||||||
resolution: {integrity: sha512-Lm+fYpMfZoEucJ7cMxgt4dYt8jLfbpwRCzAjm9UgSLOkmlqo9gupxt6YX3DY0Fk155NT9l17d/ydi+964uS9Lw==}
|
resolution: {integrity: sha512-Lm+fYpMfZoEucJ7cMxgt4dYt8jLfbpwRCzAjm9UgSLOkmlqo9gupxt6YX3DY0Fk155NT9l17d/ydi+964uS9Lw==}
|
||||||
engines: {node: '>=14.0.0'}
|
engines: {node: '>=14.0.0'}
|
||||||
@ -2584,6 +2600,11 @@ packages:
|
|||||||
object.values: 1.1.7
|
object.values: 1.1.7
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/jwt-decode@4.0.0:
|
||||||
|
resolution: {integrity: sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==}
|
||||||
|
engines: {node: '>=18'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/keyv@4.5.4:
|
/keyv@4.5.4:
|
||||||
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
|
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
@ -62,16 +62,20 @@ const apiUserLogout = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Function for Google login
|
// Function for Google login
|
||||||
const googleLogin = async (accessToken) => {
|
const googleLogin = async (accesstoken) => {
|
||||||
|
axios.defaults.withCredentials = true
|
||||||
let res = await axios.post(
|
let res = await axios.post(
|
||||||
"http://localhost:8000/api/dj-rest-auth/google/",
|
"http://localhost:8000/api/dj-rest-auth/google/",
|
||||||
{
|
{
|
||||||
access_token: accessToken,
|
access_token: accesstoken,
|
||||||
|
id_token: accesstoken,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
// console.log('service google login res: ', res);
|
||||||
return await res;
|
return await res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Function to get 'hello' data
|
// Function to get 'hello' data
|
||||||
const getGreeting = () => {
|
const getGreeting = () => {
|
||||||
return axiosInstance
|
return axiosInstance
|
||||||
|
|||||||
@ -1,19 +1,20 @@
|
|||||||
import { AnimatePresence, motion } from "framer-motion";
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import {
|
import { AnimatePresence, motion } from "framer-motion";
|
||||||
SiFramer,
|
import { SiFramer, SiTailwindcss, SiReact, SiJavascript, SiCss3 } from "react-icons/si";
|
||||||
SiTailwindcss,
|
|
||||||
SiReact,
|
|
||||||
SiJavascript,
|
|
||||||
SiCss3,
|
|
||||||
} from "react-icons/si";
|
|
||||||
|
|
||||||
import homeLogo from "../assets/home.png";
|
import homeLogo from "../assets/home.png";
|
||||||
import calendarLogo from "../assets/calendar.png";
|
import calendarLogo from "../assets/calendar.png";
|
||||||
import planLogo from "../assets/planning.png";
|
import planLogo from "../assets/planning.png";
|
||||||
import pieLogo from "../assets/pie-chart.png";
|
import pieLogo from "../assets/pie-chart.png";
|
||||||
import plusLogo from "../assets/plus.png";
|
import plusLogo from "../assets/plus.png";
|
||||||
|
|
||||||
|
const menuItems = [
|
||||||
|
{ id: 0, icon: <homeLogo />, logo: homeLogo },
|
||||||
|
{ id: 1, icon: <calendarLogo />, logo: calendarLogo },
|
||||||
|
{ id: 2, icon: <planLogo />, logo: planLogo },
|
||||||
|
{ id: 3, icon: <pieLogo />, logo: pieLogo },
|
||||||
|
{ id: 4, icon: <plusLogo />, logo: plusLogo },
|
||||||
|
];
|
||||||
|
|
||||||
const IconSideNav = () => {
|
const IconSideNav = () => {
|
||||||
return (
|
return (
|
||||||
<div className="bg-slate-900 text-slate-100 flex">
|
<div className="bg-slate-900 text-slate-100 flex">
|
||||||
@ -26,34 +27,6 @@ const IconSideNav = () => {
|
|||||||
const SideNav = () => {
|
const SideNav = () => {
|
||||||
const [selected, setSelected] = useState(0);
|
const [selected, setSelected] = useState(0);
|
||||||
|
|
||||||
const menuItems = [
|
|
||||||
{
|
|
||||||
id: 0,
|
|
||||||
icon: <homeLogo />,
|
|
||||||
logo: homeLogo,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
icon: <calendarLogo />,
|
|
||||||
logo: calendarLogo,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
icon: <planLogo />,
|
|
||||||
logo: planLogo,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
icon: <pieLogo />,
|
|
||||||
logo: pieLogo,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 4,
|
|
||||||
icon: <plusLogo />,
|
|
||||||
logo: plusLogo,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<nav className="h-[500px] w-fit bg-slate-950 p-4 flex flex-col items-center gap-2">
|
<nav className="h-[500px] w-fit bg-slate-950 p-4 flex flex-col items-center gap-2">
|
||||||
{menuItems.map((item) => (
|
{menuItems.map((item) => (
|
||||||
@ -73,7 +46,7 @@ const SideNav = () => {
|
|||||||
const NavItem = ({ icon, selected, id, setSelected, logo }) => {
|
const NavItem = ({ icon, selected, id, setSelected, logo }) => {
|
||||||
return (
|
return (
|
||||||
<motion.button
|
<motion.button
|
||||||
className="p-3 text-xl bg-slate-800 hover:bg-slate-700 rounded-md transition-colors relative"
|
className="p-3 text-xl bg-slate-800 hover-bg-slate-700 rounded-md transition-colors relative"
|
||||||
onClick={() => setSelected(id)}
|
onClick={() => setSelected(id)}
|
||||||
whileHover={{ scale: 1.05 }}
|
whileHover={{ scale: 1.05 }}
|
||||||
whileTap={{ scale: 0.95 }}
|
whileTap={{ scale: 0.95 }}
|
||||||
@ -96,5 +69,4 @@ const NavItem = ({ icon, selected, id, setSelected, logo }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export default IconSideNav;
|
export default IconSideNav;
|
||||||
@ -8,10 +8,8 @@ import { makeStyles } from '@material-ui/core/styles';
|
|||||||
import Container from '@material-ui/core/Container';
|
import Container from '@material-ui/core/Container';
|
||||||
import axiosapi from '../api/axiosapi';
|
import axiosapi from '../api/axiosapi';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { GoogleLogin } from 'react-google-login';
|
import { useGoogleLogin } from '@react-oauth/google';
|
||||||
|
import { useHistory } from 'react-router-dom';
|
||||||
|
|
||||||
const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID
|
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
// Styles for various elements
|
// Styles for various elements
|
||||||
@ -35,7 +33,7 @@ const useStyles = makeStyles((theme) => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
export default function Login() {
|
export default function Login() {
|
||||||
const history = useNavigate();
|
const history = useHistory();
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
|
|
||||||
const [email, setEmail] = useState("");
|
const [email, setEmail] = useState("");
|
||||||
@ -79,7 +77,7 @@ export default function Login() {
|
|||||||
|
|
||||||
const responseGoogle = async (response) => {
|
const responseGoogle = async (response) => {
|
||||||
// Handle Google login response
|
// Handle Google login response
|
||||||
let googleResponse = await axiosapi.googleLogin(response.accessToken);
|
let googleResponse = await axiosapi.googleLogin(response.access_token);
|
||||||
console.log('Google Response:\n', googleResponse);
|
console.log('Google Response:\n', googleResponse);
|
||||||
|
|
||||||
if (googleResponse.status === 200) {
|
if (googleResponse.status === 200) {
|
||||||
@ -91,6 +89,13 @@ export default function Login() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const googleLoginflow = useGoogleLogin({
|
||||||
|
onSuccess: async tokenResponse => {
|
||||||
|
console.log(tokenResponse);
|
||||||
|
responseGoogle(tokenResponse);
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container component="main" maxWidth="xs">
|
<Container component="main" maxWidth="xs">
|
||||||
<CssBaseline />
|
<CssBaseline />
|
||||||
@ -147,13 +152,10 @@ export default function Login() {
|
|||||||
</Button>
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<GoogleLogin
|
|
||||||
clientId={GOOGLE_CLIENT_ID}
|
<button onClick={() => googleLoginflow()}>
|
||||||
buttonText="Login"
|
Sign in with Google 🚀{' '}
|
||||||
onSuccess={responseGoogle}
|
</button>
|
||||||
onFailure={responseGoogle}
|
|
||||||
cookiePolicy={'single_host_origin'}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,7 +1,13 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom/client";
|
||||||
import App from "./App";
|
import App from "./App";
|
||||||
|
import { GoogleLogin, GoogleOAuthProvider} from '@react-oauth/google';
|
||||||
|
|
||||||
|
const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID
|
||||||
|
|
||||||
|
|
||||||
ReactDOM.createRoot(document.getElementById("root")).render(
|
ReactDOM.createRoot(document.getElementById("root")).render(
|
||||||
|
<GoogleOAuthProvider clientId={GOOGLE_CLIENT_ID}>
|
||||||
<App />
|
<App />
|
||||||
|
</GoogleOAuthProvider>
|
||||||
);
|
);
|
||||||
Loading…
Reference in New Issue
Block a user