Ver código fonte

Added Google authentication

master
Lazar Kostic 3 anos atrás
pai
commit
5181fc2e11

+ 13
- 18
src/AppRoutes.js Ver arquivo

@@ -1,5 +1,5 @@
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 {
LOGIN_PAGE,
@@ -8,33 +8,28 @@ import {
NOT_FOUND_PAGE,
ERROR_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 = () => (
<Switch>
<Route exact path={BASE_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={ERROR_PAGE} component={ErrorPage} />
<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} />
</Switch>
);


export default AppRoutes;

+ 2
- 1
src/constants/pages.js Ver arquivo

@@ -3,4 +3,5 @@ export const LOGIN_PAGE = '/login';
export const FORGOT_PASSWORD_PAGE = '/forgot-password';
export const HOME_PAGE = '/home';
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 Ver arquivo

@@ -0,0 +1,61 @@
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 Ver arquivo

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

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

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

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

+ 15
- 4
src/pages/LoginPage/LoginPageMUI.js Ver arquivo

@@ -26,11 +26,10 @@ import { Visibility, VisibilityOff } from "@mui/icons-material";
import Backdrop from "../../components/MUI/BackdropComponent";
import ErrorMessage from "../../components/MUI/ErrorMessageComponent";
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 loginInitialValues from "../../initialValues/loginInitialValues";
import GoogleIcon from "@mui/icons-material/Google";

const LoginPage = ({ history }) => {
const dispatch = useDispatch();
@@ -41,6 +40,10 @@ const LoginPage = ({ history }) => {
const handleClickShowPassword = () => 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
useEffect(() => {
dispatch(clearLoginErrors());
@@ -58,7 +61,7 @@ const LoginPage = ({ history }) => {
};

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

+ 1
- 1
src/request/index.js Ver arquivo

@@ -6,7 +6,7 @@ const request = axios.create({
headers: {
"Content-Type": "application/json",
},
withCredentials: true,
// withCredentials: true,
// paramsSerializer: (params) =>
// queryString.stringify(params, { arrayFormat: 'comma' }),
});

+ 1
- 3
src/store/middleware/accessTokenMiddleware.js Ver arquivo

@@ -4,8 +4,6 @@ import { JWT_REFRESH_TOKEN, JWT_TOKEN } from "../../constants/localStorage";
import { attachBeforeRequestListener } from "../../request/index";
import { authScopeStringGetHelper } from "../../util/helpers/authScopeHelpers";
import { logoutUser, refreshUserToken } from "../actions/login/loginActions";
import { apiDefaultUrl } from "../../request/index";
import apiEndpoints from "../../request/apiEndpoints";

export const accessTokensMiddlewareInterceptorName = "ACCESS_TOKEN_INTERCEPTOR";

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

Carregando…
Cancelar
Salvar