Я настраиваю проект create-реакции и в настоящее время работаю над частью аутентификации, чтобы войти в профиль пользователя с помощью auth0.Я запустил код независимо (скачанный с веб-сайта auth0), и он сработал, однако, когда я скомбинировал его с существующим проектом, он не выглядел должным образом.
У меня есть 4 основных файла js, которые являются индексными.js, main.js, Home.js (Component) и rout.js для рендеринга домашней страницы.
package.json файл (только зависимости)
"dependencies": {
"@material-ui/core": "^4.0.2",
"auth0-js": "^9.10.4",
"bootstrap": "^4.3.1",
"clsx": "1.0.4",
"react": "16.8.6",
"react-bootstrap": "^1.0.0-beta.9",
"react-dom": "16.8.6",
"react-router-dom": "^5.0.1",
"react-scripts": "2.1.8"
},
index.js file
import React, { Component } from "react";
import ReactDOM from "react-dom";
import { createMuiTheme, MuiThemeProvider } from "@material-
ui/core/styles";
import deepOrange from "@material-ui/core/colors/deepOrange";
//for auth0
import "bootstrap/dist/css/bootstrap.css";
import { makeMainRoutes } from "./routes";
import { Navbar, Button } from "react-bootstrap";
import Home from "./components/Home";
//react-router-dom
import "./styles.css";
class App extends Component {
goTo(route) {
this.props.history.replace(`/${route}`);
}
login() {
this.props.auth.login();
}
logout() {
this.props.auth.logout();
}
componentDidMount() {
const { renewSession } = this.props.auth;
if (localStorage.getItem("isLoggedIn") === "true") {
renewSession();
}
}
render() {
const { isAuthenticated } = this.props.auth;
return (
<div>
<MuiThemeProvider
theme={createMuiTheme({
palette: {
primary: deepOrange,
secondary: deepOrange
}
})}
/>
<Home />
<Navbar fluid>
<Navbar.Header>
<Navbar.Brand>
<a href="#">Auth0 - React</a>
</Navbar.Brand>
<Button
bsStyle="primary"
className="btn-margin"
onClick={this.goTo.bind(this, "home")}
>
Home
</Button>
{!isAuthenticated() && (
<Button
id="qsLoginBtn"
bsStyle="primary"
className="btn-margin"
onClick={this.login.bind(this)}
>
Log In
</Button>
)}
{isAuthenticated() && (
<Button
id="qsLogoutBtn"
bsStyle="primary"
className="btn-margin"
onClick={this.logout.bind(this)}
>
Log Out
</Button>
)}
</Navbar.Header>
</Navbar>
</div>
);
}
}
export default App;
const routes = makeMainRoutes();
ReactDOM.render(routes, document.getElementById("root"));
main.js
import React, { useState } from "react";
import { createMuiTheme, MuiThemeProvider } from "@material-
ui/core/styles";
import CssBaseline from "@material-ui/core/CssBaseline";
import Icon from "@material-ui/core/Icon";
import deepOrange from "@material-ui/core/colors/deepOrange";
import { Root, Header, Nav, Content, Footer, presets } from
"./Layout";
import NavContentEx from "./components/NavContentEx";
import NavHeaderEx from "./components/NavHeaderEx";
import HeaderEx from "./components/HeaderEx";
import ContentEx from "./components/ContentEx";
import FooterEx from "./components/FooterEx";
import MediaCard from "./components/Card";
function Main() {
const [loading] = useState(false);
const [preset] = useState("createDefaultLayout");
const [data] = useState({
header: true,
nav: true,
content: true,
footer: true
});
return (
<MuiThemeProvider
theme={createMuiTheme({
palette: {
primary: deepOrange,
secondary: deepOrange
}
})}
>
{loading ? (
<div
style={{
height: "100vh",
display: "flex",
justifyContent: "center",
alignItems: "center"
}}
/>
) : (
<Root config={presets[preset]()} style={{ minHeight: "100vh" }}>
<CssBaseline />
<Header
menuIcon={{
inactive: <Icon>menu_rounded</Icon>,
active: <Icon>chevron_left</Icon>
}}
>
{({ screen, collapsed }) =>
data.header && <HeaderEx screen={screen} collapsed=
{collapsed} />
}
</Header>
<Nav
collapsedIcon={{
inactive: <Icon>chevron_left</Icon>,
active: <Icon>chevron_right</Icon>
}}
header={({ collapsed }) =>
data.nav && <NavHeaderEx collapsed={collapsed} />
}
>
{data.nav && <NavContentEx />}
</Nav>
<Content>
<div>
<MediaCard />
</div>
{data.content && <ContentEx />}
</Content>
<Footer>{data.footer && <FooterEx />}</Footer>
</Root>
)}
</MuiThemeProvider>
);
}
export default Main;
rout.js
import React from "react";
import { Route, BrowserRouter, Switch } from "react-router-dom";
import App from "./index";
import Main from "./main";
import Callback from "./Callback/Callback";
import Auth from "./Auth/Auth";
import history from "./history";
const auth = new Auth();
const handleAuthentication = ({ location }) => {
if (/access_token|id_token|error/.test(location.hash)) {
auth.handleAuthentication();
}
};
export const makeMainRoutes = () => {
return (
<BrowserRouter history={history}>
<Switch>
<Route path="/" render={props => <App auth={auth} {...props}
/>} />
<Route path="/main" render={props => <Main auth={auth}
{...props} />} />
<Route
path="/callback"
render={props => {
handleAuthentication(props);
return <Callback {...props} />;
}}
/>
</Switch>
</BrowserRouter>
);
};
Home.js
import React, { Component } from 'react';
class Home extends Component {
login() {
this.props.auth.login();
}
render() {
const { isAuthenticated } = this.props.auth;
return (
<div className="container">
{
isAuthenticated() && (
<h4>
You are logged in!
</h4>
)
}
{
!isAuthenticated() && (
<h4>
You are not logged in! Please{' '}
<a style={{ cursor: 'pointer' }}
onClick={this.login.bind(this)}>
Log In
</a>
{' '}to continue.
</h4>
)
}
</div>
);
}
}
export default Home;
РЕДАКТИРОВАТЬ * Auth.js fileдобавлено
import history from "../history";
import auth0 from "auth0-js";
import { AUTH_CONFIG } from "./auth0-variables";
export default class Auth {
accessToken;
idToken;
expiresAt;
auth0 = new auth0.WebAuth({
domain: AUTH_CONFIG.domain,
clientID: AUTH_CONFIG.clientID,
redirectUri: AUTH_CONFIG.callbackUrl,
responseType: "token id_token",
scope: "openid"
});
constructor() {
this.login = this.login.bind(this);
this.logout = this.logout.bind(this);
this.handleAuthentication = this.handleAuthentication.bind(this);
this.isAuthenticated = this.isAuthenticated.bind(this);
this.getAccessToken = this.getAccessToken.bind(this);
this.getIdToken = this.getIdToken.bind(this);
this.renewSession = this.renewSession.bind(this);
}
login() {
this.auth0.authorize();
}
handleAuthentication() {
this.auth0.parseHash((err, authResult) => {
if (authResult && authResult.accessToken && authResult.idToken) {
this.setSession(authResult);
} else if (err) {
history.replace("/main");
console.log(err);
alert(`Error: ${err.error}. Check the console for further
details.`);
}
});
}
getAccessToken() {
return this.accessToken;
}
getIdToken() {
return this.idToken;
}
setSession(authResult) {
// Set isLoggedIn flag in localStorage
localStorage.setItem("isLoggedIn", "true");
// Set the time that the access token will expire at
let expiresAt = authResult.expiresIn * 1000 + new Date().getTime();
this.accessToken = authResult.accessToken;
this.idToken = authResult.idToken;
this.expiresAt = expiresAt;
// navigate to the home route
history.replace("/main");
}
renewSession() {
this.auth0.checkSession({}, (err, authResult) => {
if (authResult && authResult.accessToken && authResult.idToken) {
this.setSession(authResult);
} else if (err) {
this.logout();
console.log(err);
alert(
`Could not get a new token (${err.error}:
${err.error_description}).`
);
}
});
}
logout() {
// Remove tokens and expiry time
this.accessToken = null;
this.idToken = null;
this.expiresAt = 0;
// Remove isLoggedIn flag from localStorage
localStorage.removeItem("isLoggedIn");
this.auth0.logout({
returnTo: window.location.origin
});
// navigate to the home route
history.replace("/main");
}
isAuthenticated() {
// Check whether the current time is past the
// access token's expiry time
let expiresAt = this.expiresAt;
return new Date().getTime() < expiresAt;
}
}
Некоторые ошибки приведены ниже;
- Недопустимый тип элемента: ожидается строка (для встроенных компонентов) или класс / функция (для составного)компоненты), но получил: не определено.Вероятно, вы забыли экспортировать свой компонент из файла, в котором он определен, или вы перепутали импорт по умолчанию и имена.
Проверьте метод рендеринга App
. "
TypeError: Невозможно прочитать свойство isAuthenticated из неопределенного