Преглед изворни кода

Added Google authentication

master
Lazar Kostic пре 3 година
родитељ
комит
5181fc2e11

+ 13
- 18
src/AppRoutes.js Прегледај датотеку

import React from 'react';
import { Redirect, Route, Switch } from 'react-router-dom';
import React from "react";
import { Redirect, Route, Switch } from "react-router-dom";


import { import {
LOGIN_PAGE, LOGIN_PAGE,
NOT_FOUND_PAGE, NOT_FOUND_PAGE,
ERROR_PAGE, ERROR_PAGE,
BASE_PAGE, BASE_PAGE,
} from './constants/pages';
GOOGLE_AUTH_CALLBACK_PAGE,
} from "./constants/pages";


// import LoginPage from './pages/LoginPage/LoginPage';
import LoginPage from './pages/LoginPage/LoginPageMUI';
// import HomePage from './pages/HomePage/HomePage';
import HomePage from './pages/HomePage/HomePageMUI';
import NotFoundPage from './pages/ErrorPages/NotFoundPage';
import ErrorPage from './pages/ErrorPages/ErrorPage';
// import ForgotPasswordPage from './pages/ForgotPasswordPage/ForgotPasswordPage';
import ForgotPasswordPage from './pages/ForgotPasswordPage/ForgotPasswordPageMUI';
import PrivateRoute from './components/Router/PrivateRoute';
import LoginPage from "./pages/LoginPage/LoginPageMUI";
import HomePage from "./pages/HomePage/HomePageMUI";
import NotFoundPage from "./pages/ErrorPages/NotFoundPage";
import ErrorPage from "./pages/ErrorPages/ErrorPage";
import ForgotPasswordPage from "./pages/ForgotPasswordPage/ForgotPasswordPageMUI";
import PrivateRoute from "./components/Router/PrivateRoute";
import GoogleAuthCallback from "./pages/GoogleAuthCallback/GoogleAuthCallback";


const AppRoutes = () => ( const AppRoutes = () => (
<Switch> <Switch>
<Route exact path={BASE_PAGE} component={LoginPage} /> <Route exact path={BASE_PAGE} component={LoginPage} />
<Route exact path={LOGIN_PAGE} component={LoginPage} /> <Route exact path={LOGIN_PAGE} component={LoginPage} />
<Route path={GOOGLE_AUTH_CALLBACK_PAGE} component={GoogleAuthCallback} />
<Route path={NOT_FOUND_PAGE} component={NotFoundPage} /> <Route path={NOT_FOUND_PAGE} component={NotFoundPage} />
<Route path={ERROR_PAGE} component={ErrorPage} /> <Route path={ERROR_PAGE} component={ErrorPage} />
<Route path={FORGOT_PASSWORD_PAGE} component={ForgotPasswordPage} /> <Route path={FORGOT_PASSWORD_PAGE} component={ForgotPasswordPage} />
<PrivateRoute
exact
path={HOME_PAGE}
component={HomePage}
/>
<PrivateRoute exact path={HOME_PAGE} component={HomePage} />
<Redirect from="*" to={NOT_FOUND_PAGE} /> <Redirect from="*" to={NOT_FOUND_PAGE} />
</Switch> </Switch>
); );



export default AppRoutes; export default AppRoutes;

+ 2
- 1
src/constants/pages.js Прегледај датотеку

export const FORGOT_PASSWORD_PAGE = '/forgot-password'; export const FORGOT_PASSWORD_PAGE = '/forgot-password';
export const HOME_PAGE = '/home'; export const HOME_PAGE = '/home';
export const ERROR_PAGE = '/error-page'; export const ERROR_PAGE = '/error-page';
export const NOT_FOUND_PAGE = '/not-found';
export const NOT_FOUND_PAGE = '/not-found';
export const GOOGLE_AUTH_CALLBACK_PAGE = '/api/auth/google/callback'

+ 61
- 0
src/pages/GoogleAuthCallback/GoogleAuthCallback.js Прегледај датотеку

import React, { useEffect } from "react";
import { useLocation } from "react-router-dom";
import { authScopeSetHelper } from "../../util/helpers/authScopeHelpers";
import { addHeaderToken } from "../../request";
import { HOME_PAGE } from "../../constants/pages";
import { JWT_REFRESH_TOKEN, JWT_TOKEN } from "../../constants/localStorage";
import { setUser } from "../../store/actions/user/userActions";
import PropTypes from "prop-types";
import axios from "axios";

function GoogleAuthCallback({ history }) {
const location = useLocation();

const handleApiResponseSuccess = () => {
history.push({
pathname: HOME_PAGE,
state: {
from: history.location.pathname,
},
});
};

useEffect(() => {
if (!location) {
return;
}
const { search } = location;
axios({
method: "GET",
url: `http://localhost:1337/api/auth/google/callback?${search}`,
withCredentials: true,
}).then((res) => {
if (res.data?.jwt) {
const user = res.data?.user;
authScopeSetHelper(JWT_TOKEN, res.data.jwt);
authScopeSetHelper(JWT_REFRESH_TOKEN, res.data.refreshToken);
addHeaderToken(res.data?.jwt);
setUser(user);
handleApiResponseSuccess();
}
});
}, [location]);

return (
<div>
<></>
</div>
);
}

GoogleAuthCallback.propTypes = {
history: PropTypes.shape({
replace: PropTypes.func,
push: PropTypes.func,
location: PropTypes.shape({
pathname: PropTypes.string,
}),
}),
};

export default GoogleAuthCallback;

+ 13
- 1
src/pages/HomePage/HomePageMUI.js Прегледај датотеку

import React from "react"; import React from "react";
import { Box, Grid } from "@mui/material";
import { Box, Button, Grid } from "@mui/material";
import Navbar from "../../components/MUI/NavbarComponent"; import Navbar from "../../components/MUI/NavbarComponent";
import Modals from "../../components/MUI/Examples/ModalsExample"; import Modals from "../../components/MUI/Examples/ModalsExample";
import DataGrid from "../../components/MUI/Examples/DataGridExample"; import DataGrid from "../../components/MUI/Examples/DataGridExample";
import PagingSortingFiltering from "../../components/MUI/Examples/PagingSortingFilteringExample"; import PagingSortingFiltering from "../../components/MUI/Examples/PagingSortingFilteringExample";
import PagingSortingFilteringServerSide from "../../components/MUI/Examples/PagingSortingFilteringExampleServerSide"; import PagingSortingFilteringServerSide from "../../components/MUI/Examples/PagingSortingFilteringExampleServerSide";
import RandomDataProvider from "../../context/RandomDataContext"; import RandomDataProvider from "../../context/RandomDataContext";
import { getRequest } from "../../request";


const HomePage = () => { const HomePage = () => {
const getPosts = async () => {
const {data} = await getRequest("api/posts");

console.log(data);
};
return ( return (
<> <>
<Navbar /> <Navbar />
<Box textAlign="center" marginTop={5}>
<Button onClick={getPosts} sx={{ width: "200px" }} variant="outlined">
Get Posts
</Button>
</Box>

<Box sx={{ mt: 4, mx: 4 }}> <Box sx={{ mt: 4, mx: 4 }}>
<Grid container spacing={2} justifyContent="center"> <Grid container spacing={2} justifyContent="center">
<Grid item xs={12} md={3}> <Grid item xs={12} md={3}>

+ 15
- 4
src/pages/LoginPage/LoginPageMUI.js Прегледај датотеку

import Backdrop from "../../components/MUI/BackdropComponent"; import Backdrop from "../../components/MUI/BackdropComponent";
import ErrorMessage from "../../components/MUI/ErrorMessageComponent"; import ErrorMessage from "../../components/MUI/ErrorMessageComponent";
import { selectIsLoadingByActionType } from "../../store/selectors/loadingSelectors"; import { selectIsLoadingByActionType } from "../../store/selectors/loadingSelectors";
import {
LOGIN_USER_SCOPE,
} from "../../store/actions/login/loginActionConstants";
import { LOGIN_USER_SCOPE } from "../../store/actions/login/loginActionConstants";
import loginValidation from "../../validations/loginValidation"; import loginValidation from "../../validations/loginValidation";
import loginInitialValues from "../../initialValues/loginInitialValues"; import loginInitialValues from "../../initialValues/loginInitialValues";
import GoogleIcon from "@mui/icons-material/Google";


const LoginPage = ({ history }) => { const LoginPage = ({ history }) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const handleClickShowPassword = () => setShowPassword(!showPassword); const handleClickShowPassword = () => setShowPassword(!showPassword);
const handleMouseDownPassword = () => setShowPassword(!showPassword); const handleMouseDownPassword = () => setShowPassword(!showPassword);


const handleGoogle = () => {
window.location = "http://localhost:1337/api/connect/google";
};

// Clear login errors when user firstly enters the page // Clear login errors when user firstly enters the page
useEffect(() => { useEffect(() => {
dispatch(clearLoginErrors()); dispatch(clearLoginErrors());
}; };


const handleSubmit = (values) => { const handleSubmit = (values) => {
const { email, password} = values;
const { email, password } = values;
dispatch(clearLoginErrors()); dispatch(clearLoginErrors());
dispatch( dispatch(
fetchUser({ fetchUser({
> >
{t("login.logIn")} {t("login.logIn")}
</Button> </Button>
<Button
onClick={handleGoogle}
startIcon={<GoogleIcon />}
fullWidth
variant="outlined"
>
Connect with Google
</Button>
<Grid container> <Grid container>
<Grid <Grid
item item

+ 1
- 1
src/request/index.js Прегледај датотеку

headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
withCredentials: true,
// withCredentials: true,
// paramsSerializer: (params) => // paramsSerializer: (params) =>
// queryString.stringify(params, { arrayFormat: 'comma' }), // queryString.stringify(params, { arrayFormat: 'comma' }),
}); });

+ 1
- 3
src/store/middleware/accessTokenMiddleware.js Прегледај датотеку

import { attachBeforeRequestListener } from "../../request/index"; import { attachBeforeRequestListener } from "../../request/index";
import { authScopeStringGetHelper } from "../../util/helpers/authScopeHelpers"; import { authScopeStringGetHelper } from "../../util/helpers/authScopeHelpers";
import { logoutUser, refreshUserToken } from "../actions/login/loginActions"; import { logoutUser, refreshUserToken } from "../actions/login/loginActions";
import { apiDefaultUrl } from "../../request/index";
import apiEndpoints from "../../request/apiEndpoints";


export const accessTokensMiddlewareInterceptorName = "ACCESS_TOKEN_INTERCEPTOR"; export const accessTokensMiddlewareInterceptorName = "ACCESS_TOKEN_INTERCEPTOR";


// If access token is expired, refresh access token // If access token is expired, refresh access token
if (new Date() > new Date(jwtTokenDecoded.exp * 1000)) { if (new Date() > new Date(jwtTokenDecoded.exp * 1000)) {
const axiosResponse = await axios.post( const axiosResponse = await axios.post(
`${apiDefaultUrl}${apiEndpoints.authentications.refreshToken}`,
'http://localhost:1337/api/token/refresh',
{ {
refreshToken: refresh, refreshToken: refresh,
}, },

Loading…
Откажи
Сачувај