重定向反应路由器dom身份验证不起作用

时间:2020-03-02 21:04:33

标签: reactjs redux

登录后,它不会重定向到电池页面,因为路由认为它阻止的标题中没有令牌。我正在尝试两天以上,请好心人。后端的所有逻辑已经完美运行。用户无法替代路径来登录并生成令牌。系统将其重定向到电池路线

登录类

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;
    }

}

1 个答案:

答案 0 :(得分:0)

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

与认证问题有关,这似乎是因为在应用程序加载时Router模块已经设置了responseIsAuthenticated值,从而提前评估了令牌状态。为了确保始终评估当前状态,您必须在isAuthenticated属性内调用render方法:

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 /> */