Skip to content
This repository has been archived by the owner on May 31, 2021. It is now read-only.

Commit

Permalink
Merge pull request #222 from SoyBeansLab/feature/auth0
Browse files Browse the repository at this point in the history
認証周りの実装
  • Loading branch information
ucpr authored Apr 20, 2020
2 parents 76e69ea + c9d0598 commit 7d3ee1f
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 6 deletions.
42 changes: 40 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@auth0/auth0-spa-js": "^1.7.0",
"@material-ui/core": "^4.9.5",
"@nteract/markdown": "^4.3.7",
"@types/react-slick": "^0.23.4",
"axios": "^0.19.2",
"axios-mock-adapter": "^1.17.0",
"codemirror": "^5.52.0",
"history": "^4.10.1",
"onchange": "^6.1.0",
"prop-types": "^15.7.2",
"qs": "^6.9.1",
Expand Down
29 changes: 29 additions & 0 deletions src/atoms/app-button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from "react";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/core/styles";
import Button from "@material-ui/core/Button";

const useStyles = makeStyles(theme => ({
button: {
marginRight: theme.spacing(2),
color: "#ffffff",
},
}));

export default function LinkButton(props) {
const style = useStyles();
const text = props.text || "";
const onClick = props.onClick || function() {};

return (
<Button color="inherit" className={style} onClick={onClick}>
{text}
</Button>
);
}

LinkButton.propTypes = {
style: PropTypes.object,
text: PropTypes.string,
onClick: PropTypes.func,
};
16 changes: 15 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,26 @@ import App from "./App";
import * as serviceWorker from "./serviceWorker";
import { MuiThemeProvider } from "@material-ui/core/styles";
import { theme } from "./materialui/theme";
import { Auth0Provider } from "./react-auth0-spa";
import history from "./utils/history";
import { config } from "./config";
require("./styles/main.css");

const onRedirectCallback = appState => {
history.push(appState && appState.targetUrl ? appState.targetUrl : window.location.pathname);
};

ReactDOM.render(
// 配色を適応
<MuiThemeProvider theme={theme}>
<App />
<Auth0Provider
domain={config.AUTH0_DOMAIN}
client_id={config.AUTH0_CLIENT_ID}
redirect_uri={window.location.origin}
onRedirectCallback={onRedirectCallback}
>
<App />
</Auth0Provider>
</MuiThemeProvider>,
document.getElementById("root")
);
Expand Down
17 changes: 15 additions & 2 deletions src/molecules/HeaderAppBar.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import React from "react";
import PropTypes from "prop-types";
import AppBar from "@material-ui/core/AppBar";
import Toolbar from "@material-ui/core/Toolbar";
import Container from "@material-ui/core/Container";
import LinkButton from "../atoms/app-link-button";
import Button from "../atoms/app-button";
import LinkTitleImage from "./LinkTitleImage";

export default function HeaderAppBar() {
export default function HeaderAppBar(props) {
// const user = props.user;
const isAuthenticated = props.isAuthenticated;
const loginWithRedirect = props.loginWithRedirect;

return (
<AppBar color="primary" position="static">
<Toolbar>
Expand All @@ -15,8 +21,15 @@ export default function HeaderAppBar() {

<LinkButton to="/" text="HOME" />
<LinkButton to="/contests" text="CONTESTS" />
<LinkButton to="/signin" text="SIGN IN" />
{!isAuthenticated && <Button text="SIGN IN" onClick={loginWithRedirect} />}
{isAuthenticated && <Button text="SIGN OUT" onClick={loginWithRedirect} />}
</Toolbar>
</AppBar>
);
}

HeaderAppBar.propTypes = {
user: PropTypes.object,
isAuthenticated: PropTypes.bool,
loginWithRedirect: PropTypes.object,
};
10 changes: 9 additions & 1 deletion src/organisms/Header.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import HeaderAppBar from "../molecules/HeaderAppBar";
import { useAuth0 } from "../react-auth0-spa";

const useStyles = makeStyles(theme => ({
root: {
Expand All @@ -19,10 +20,17 @@ const useStyles = makeStyles(theme => ({

export default function Header() {
const classes = useStyles();
const { user, isAuthenticated, loginWithRedirect, logout } = useAuth0();

// eslint-disable-next-line
const logoutWithRedirect = () =>
logout({
returnTo: window.location.origin,
});

return (
<div className={classes.root}>
<HeaderAppBar />
<HeaderAppBar user={user} isAuthenticated={isAuthenticated} loginWithRedirect={loginWithRedirect} />
</div>
);
}
86 changes: 86 additions & 0 deletions src/react-auth0-spa.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
https://github.com/auth0-samples/auth0-react-samples/blob/master/01-Login/src/react-auth0-spa.js
**/

import React, { useState, useEffect, useContext } from "react";
import createAuth0Client from "@auth0/auth0-spa-js";

const DEFAULT_REDIRECT_CALLBACK = () => window.history.replaceState({}, document.title, window.location.pathname);

export const Auth0Context = React.createContext();
export const useAuth0 = () => useContext(Auth0Context);
// eslint-disable-next-line
export const Auth0Provider = ({ children, onRedirectCallback = DEFAULT_REDIRECT_CALLBACK, ...initOptions }) => {
const [isAuthenticated, setIsAuthenticated] = useState();
const [user, setUser] = useState();
const [auth0Client, setAuth0] = useState();
const [loading, setLoading] = useState(true);
const [popupOpen, setPopupOpen] = useState(false);

useEffect(() => {
const initAuth0 = async () => {
const auth0FromHook = await createAuth0Client(initOptions);
setAuth0(auth0FromHook);

if (window.location.search.includes("code=") && window.location.search.includes("state=")) {
const { appState } = await auth0FromHook.handleRedirectCallback();
onRedirectCallback(appState);
}

const isAuthenticated = await auth0FromHook.isAuthenticated();

setIsAuthenticated(isAuthenticated);

if (isAuthenticated) {
const user = await auth0FromHook.getUser();
setUser(user);
}

setLoading(false);
};
initAuth0();
// eslint-disable-next-line
}, []);

const loginWithPopup = async (params = {}) => {
setPopupOpen(true);
try {
await auth0Client.loginWithPopup(params);
} catch (error) {
console.error(error);
} finally {
setPopupOpen(false);
}
const user = await auth0Client.getUser();
setUser(user);
setIsAuthenticated(true);
};

const handleRedirectCallback = async () => {
setLoading(true);
await auth0Client.handleRedirectCallback();
const user = await auth0Client.getUser();
setLoading(false);
setIsAuthenticated(true);
setUser(user);
};
return (
<Auth0Context.Provider
value={{
isAuthenticated,
user,
loading,
popupOpen,
loginWithPopup,
handleRedirectCallback,
getIdTokenClaims: (...p) => auth0Client.getIdTokenClaims(...p),
loginWithRedirect: (...p) => auth0Client.loginWithRedirect(...p),
getTokenSilently: (...p) => auth0Client.getTokenSilently(...p),
getTokenWithPopup: (...p) => auth0Client.getTokenWithPopup(...p),
logout: (...p) => auth0Client.logout(...p),
}}
>
{children}
</Auth0Context.Provider>
);
};
2 changes: 2 additions & 0 deletions src/utils/history.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { createBrowserHistory } from "history";
export default createBrowserHistory();

0 comments on commit 7d3ee1f

Please sign in to comment.