重定向react路由器dom auth不工作



登录后重定向到电池页面不会失败,因为路由认为它在阻止的标头中没有令牌。我试了两天以上,请好心人。后端的所有逻辑都已经完美地工作了。无法替换用户登录和生成令牌的路径。系统将其重定向到电池路线

登录类

import React, { Component } from 'react'
import IntanceAxios from '../../components/meuaxios'
// import GlobalStyle from './style.jsx';
import Form from './Form.jsx'
import { /* useSelector, useDispatch ,*/ connect } from 'react-redux';
import { withRouter } from "react-router-dom";
import history from '../../routes/History';
class Login extends Component {
constructor() {
super();
this.handleSubmit = this.handleSubmit.bind(this);
this.handleEmailChange = this.handleEmailChange.bind(this);
this.handlePasswordChange = this.handlePasswordChange.bind(this);
this.state = {
email: JSON.parse(localStorage.getItem('isRememberUser')) ? localStorage.getItem('user') : undefined,
password: undefined,
signIn: {
success: undefined,
message: undefined,
load: undefined,
type_error: 'error'
},
fieldErrors: {
email: {
message: '',
isValid: true
},
password: {
message: '',
isValid: true
}
},
logged: false,
loadedOne: true
}
document.title = "Login"
}
// Initialization
componentWillMount() {
let isRememberUser = JSON.parse(localStorage.getItem('isRememberUser'))
if (isRememberUser && localStorage.getItem('user') === null) {
localStorage.removeItem('isRememberUser')
}
}
// Monteded
componentDidMount() {
this.setState({
loadedOne: false
})
}
validEmail = email => {
// eslint-disable-next-line no-useless-escape
const validEmailRegex = RegExp(/^(([^<>()[].,;:s@"]+(.[^<>()[].,;:s@"]+)*)|(".+"))@(([^<>()[].,;:s@"]+.)+[^<>()[].,;:s@"]{2,})$/i);
return validEmailRegex.test(email)
}
handleEmailChange(e) {
var value = e.target.value
let fieldEmail = this.validEmail(value) ? true : false;
let message = fieldEmail ? '' : 'Email esta inválido'
this.setState(prevState => {
return {
email: value,
fieldErrors: {
email: {
message: message,
isValid: fieldEmail
},
password: {
message: prevState.fieldErrors.password.message,
isValid: prevState.fieldErrors.password.isValid
}
}
}
})
}
handlePasswordChange(e) {
var value = e.target.value
let fieldPassoword =
value.length < 8 ? false : true;
let message = fieldPassoword ? '' : 'A senha deve conter mais de 8 caracteres!'
this.setState(prevState => {
return {
password: value,
fieldErrors: {
password: {
message: message,
isValid: fieldPassoword
},
email: {
message: prevState.fieldErrors.email.message,
isValid: prevState.fieldErrors.email.isValid
}
}
}
})
}
isValid() {
let { email, password } = this.state.fieldErrors
if (email.isValid && password.isValid) {
return true
}
return false
}
setUserRemember = () => {
if (JSON.parse(localStorage.getItem('isRememberUser'))) {
localStorage.setItem('user', this.state.email)
}
return;
}
setToken = token => {
return localStorage.setItem('ISA)_TOKEN', token);
}
async handleSubmit(event) {
event.preventDefault();
if (!this.state.email || this.state.email === undefined || this.state.password === undefined || !this.state.password) {
this.setState(prevState => {
return {
...this.state,
signIn: {
message: 'E-mail ou senha vazio',
success: false,
type_error: 'error'
}, logged: false,
fieldErrors: {
password: {
message: prevState.fieldErrors.password.message,
isValid: false
},
email: {
message: prevState.fieldErrors.email.message,
isValid: false
}
}
}
})
return null;
}
if (this.isValid()) {
this.setUserRemember();
this.setState({
...this.state,
signIn: {
load: true,
success: undefined,
type_error: undefined
}
});
// console.log(dataToSend);
let dataToSend = {
email: this.state.email,
password: this.state.password
}
let url = '/auth/login';
await IntanceAxios.post(url, dataToSend)
.then(response => response.data)
.then(responseData => {
if (responseData.success) {
// this.props.disparaLogin();
// this.props.verificarToken();
this.setToken(responseData.token)
this.setState({
...this.state,
signIn: {
success: true,
message: responseData.message,
}, logged: true
, status: true
});
let { from } = this.props.location || { from: { pathname: "/batteries" } };
console.log(from)
history.replace(from)
// history.replace(from);
// REDIRECIONA PARA O LOCAL RAIZ, FEITO NA UNHA
// this.setState({ redirectToReferrer: true });
} else {
this.setState({
...this.state,
signIn: {
success: false,
message: responseData.message,
type_error: 'error'
}, status: false
, logged: false,
})
}
}).catch(error => {
this.removeRember();
this.setState({
...this.state,
signIn: {
success: false,
message: error.message,
type_error: 'error'
}, status: false
, logged: false,
});
console.log(error);
});
} else {
this.removeRember()
return;
}
}
removeRember = () => {
if (localStorage.getItem('user') !== null) {
localStorage.removeItem('user')
localStorage.setItem('isRememberUser', false)
}
return;
}

render() {
const { signIn, fieldErrors, email, password, loadedOne } = this.state
return (
<>
{/* <Header /> */}
{/* <GlobalStyle /> */}
<Form loadedOne={loadedOne} signIn={signIn} email={email} password={password} fieldErrors={fieldErrors} handleSubmit={this.handleSubmit.bind()} handleEmailChange={this.handleEmailChange.bind()} handlePasswordChange={this.handlePasswordChange.bind()} />
</>
)
}
}
// export default Login;
const mapearAcoes = dispatch => {
return {
disparaLogin: () => dispatch({ type: 'SIGN_IN' }),
verificarToken: () => dispatch({ type: 'vericarToken' })
}
}
export default withRouter(Login);

路由

import React from 'react';
// Controllers 
import Login from '../views/Login/Login.jsx';
import Register from '../views/Register/Register.jsx';
import Logout from '../views/Logout/Logout.jsx';
import MapRealtime from '../views/MapRealtime/MapRealtime.jsx';
import DashBoardBaterry from '../views/DashBoardBaterry/DashBoardBaterry.jsx';
// import Painel from '../views/Painel/Painel.jsx';
// Autenthenticated of user
import { isAuthenticated } from '../components/auth.jsx';
// package of routes
import { BrowserRouter, Route, Switch, Redirect } from 'react-router-dom';
// import { Router, hashHistory } from 'react-router';
// Response of validation of key token
const responseIsAuthenticated = isAuthenticated();
// Verify if user to be logged and permited access some outhers pages, case otherwise redirection for the login 
const PrivateRoute = ({ component: Component, ...rest }) => (
<Route  {...rest} render={props => (
responseIsAuthenticated ? (
<Component {...props} />
) : (
<Redirect to={{ pathname: "/login", state: { from: props.location } }} />
)
)} />
)
alert(responseIsAuthenticated)
// Verify if user to be logged and redirection for the APP
const Authenticated = ({ component: Component, ...rest }) => (
<Route {...rest} render={props => (
responseIsAuthenticated ? (
<Redirect to={{ pathname: "/batteries", state: { from: props.location } }} />
) : (
<Component {...props} />
)
)} />
)
const Routes = () => (
<BrowserRouter>
<Switch>
<Route exact path="/" component={() => <h1>Home page</h1>} />
<Route path="/logout" component={Logout} />
<PrivateRoute exact path="/maprealtime" component={MapRealtime} />
<PrivateRoute exact path="/batteries" component={DashBoardBaterry} />
{/* <PrivateRoute path="/account" component={() => <h1>Account</h1>} /> */}
<PrivateRoute path="/app" component={() => <h1>Autenticado</h1>} />
<Authenticated exact path="/login" component={Login} />
<Authenticated exact path="/registrar" component={Register} />
<Route path="/not-authorized" component={() => <h1>Pagina não autorizada</h1>} />
{/* This route want be a last */}
<Route path="*" component={() => <h1>NotFound</h1>} />
</Switch>
</BrowserRouter>
);
export default (Routes);

应用

import React from 'react';
// import { BrowserRouter, Route, Switch, Redirect } from 'react-router-dom';
import { Provider } from 'react-redux';
import Routes from './routes/Routes.jsx';
import store from './store/reducer';
// Verifyted of internet 
import NetworkDetector from './components/NetworkDetector.jsx'
import { ThemeProvider, createMuiTheme } from "@material-ui/core/styles";
import { blue } from '@material-ui/core/colors';
import './assets/vendor/bootstrap-4.3.1-dist/css/bootstrap.min.css';
import './assets/css/main.css';

const defaultTheme = createMuiTheme();

const theme = createMuiTheme({
palette: {
primary: {
light: '#2194f3',
main: '#2194f3',
},
secondary: {
light: '#4B4B4D',
main: '#666668',
},
colorPrimary: {
light: '#63b4f6',
main: '#2194f3',
},
colorSecondary: {
light: '#fbe53d',
main: '#fff079',
},
colorDefault: '#2194f3',
},
formControl: {
color: blue
},
spacingLi: {
paddingLeft: defaultTheme.spacing(4),
}
});
function App() {
return (
<Provider store={store}>
<ThemeProvider theme={theme}>
<Routes />
</ThemeProvider >
</Provider>
);
}
export default NetworkDetector(App);

验证用户


export const isAuthenticated = () => {
// let autheticated = false;
let token = localStorage.getItem('ISA)_TOKEN');
if (!token) {
// this.redirectToReferrer(false);
// let autheticated = false
return false
} else {
let url = 'http://localhost:5000/auth/verifytoken ';
fetch(url, {
method: "GET",
body: undefined,
headers: {
"Content-Type": "application/json",
"authorization": `Bearer ${token}`
}
})
.then(response => response.json())
.then(responseData => {
if (!responseData.success) {
localStorage.removeItem('ISA)_TOKEN');
window.location.replace('/')
return null;
}
// this.redirectToReferrer(true);

}).catch(error => {
localStorage.removeItem('ISA)_TOKEN');
window.location.replace('/')
});

return true;
}
}

上面的代码通过尝试"将文本类型的受控输入更改为不受控"来触发额外的(非相关的(警告。要解决此问题,请将FormComponent切换到Controlled策略,使用组件状态来管理输入值和验证,并将所需的方法绑定为prop来处理登录请求或一些异步验证。

与身份验证问题有关,它的出现似乎是因为在加载应用程序时,Router模块已经设置了responseIsAuthenticated值,提前评估了令牌状态。为了确保始终评估当前状态,您必须调用render道具中的isAuthenticated方法:

const PrivateRoute = ({ component: Component, ...rest }) => (
<Route  {...rest} render={props => (
// Call to isAuthenticated here.
isAuthenticated() ? (
<Component {...props} />
) : (
<Redirect to={{ pathname: "/login", state: { from: props.location } }} />
)
)} />
)

此外,为了在成功登录后重定向用户。我建议在"LoginComponent"中附加Redirect组件:

render() {
const { signIn, fieldErrors, email, password, loadedOne } = this.state
if(signIn.success)
return <Redirect to={{ pathname: "/batteries"}} />;
/* <Form /> */

最新更新