2 votes

Le routeur React affiche brièvement l'écran de connexion et redirige ensuite vers le tableau de bord si l'utilisateur est connecté.

J'ai une page de connexion, une page de tableau de bord et quelques autres. J'utilise Firebase comme backend. J'ai effectué un rendu conditionnel sur le composant de connexion pour vérifier si l'utilisateur est connecté ou non. (Si l'utilisateur est connecté, il est redirigé vers le tableau de bord). J'ai utilisé ProtectedRoutes pour le tableau de bord et d'autres pour rediriger vers la page de connexion si l'utilisateur n'est pas connecté.

ce qui se passe, c'est que lorsque je recharge la page du tableau de bord ou toute autre page alors que la connexion est vraie, je vois brièvement le composant de connexion puis il exécute le firebase " auth.onAuthStateChanged La méthode " " définit l'état de connexion à true et me redirige vers le tableau de bord. Je comprends pourquoi je vois la page de connexion, mais je ne sais pas comment y remédier.

import React, { useState } from 'react'
import { connect } from "react-redux"
import { signin, autoSignin } from "../Redux/Actions/AuthActions"
import { Redirect } from 'react-router-dom'

const Login = (props) => {

    const [form, setForm] = useState({})
    const [disable, setDisable] = useState(false)

    const handleChange = (e) => {
        setForm({
            ...form,
            [e.target.name]: e.target.value
        })
    }

    const handleSubmit = (e) => {
        setDisable(true)
        e.preventDefault()
        props.signin(form.email, form.password)
        setDisable(false)
    }

    return (
        props.auth.loggedin ?
            <Redirect to="/dashboard" /> :
            <div className="container-fluid login_screen">
                <div className="row justify-content-center">
                    <div className="col-md-4 col-xs-12">
                        <img className="img-fluid login_screen_logo mt-4" src="/images/logo.png" alt="logo" />
                        <h1 className="mt-4 fs-3 heading">LOGIN</h1>
                        <p className="fs-6 mb-3">to access dashboard</p>

                        <form onSubmit={handleSubmit}>
                            <div className="form-floating mb-4 mt-4">
                                <input name="email" onChange={handleChange} required type="email" className="form-control shadow-sm" id="floatingInput" placeholder="room@adil.tower" />
                                <label htmlFor="floatingInput">Email id</label>
                            </div>
                            <div className="form-floating mt-4">
                                <input name="password" onChange={handleChange} required type="password" className="form-control shadow-sm" id="floatingPassword" placeholder="Password" />
                                <label htmlFor="floatingPassword">Password</label>
                            </div>
                            <div className="d-grid gap-2">
                                <button type="submit" className={`btn btn-custom mt-4 btn-lg shadow ${disable ? "disabled" : ""}`}>LOGIN</button>
                            </div>
                        </form>

                    </div>
                </div>

            </div>
    )

}

const mapStateToProps = (state) => {
    return {
        auth: state.auth
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        signin: (email, pass) => dispatch(signin(email, pass)),
        autoSignin: (uid) => dispatch(autoSignin(uid))
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(Login)

import React from 'react'

const Dashboard = (props) => {

    return (
        <h1>
        dashboard
        </h1>
    )
}

export default Dashboard

import React from 'react'
import { Redirect, Route } from "react-router-dom"

const ProtectedRoute = ({ loggedin, component: Component, ...rest }) => {
    return (
        <Route
            {...rest}
            render={
                (props) => {
                    if (loggedin) {
                        return <Component {...props} />
                    } else {
                        return <Redirect to="/" />
                    }
                }
            }
        />
    )
}

export default ProtectedRoute

import React, { useEffect } from 'react'
import { BrowserRouter as Router, Switch, Route } from "react-router-dom"
import ProtectedRoute from './ProtectedRoute'
import { auth } from "./FirebaseConfig"

// SCREENS
import Dashboard from './Dashboard/Dashboard'
import Login from "./Login/Login"
import Profile from './Profile/Profile'
import Emergency from './Emergency/Emergency'
import Notice from './Notice/Notice'
import Complains from "./Complains/Complains"
import Meetings from "./Meetings/Meetings"

// REDUX STORE & ACTIONS
import { connect } from "react-redux"
import { autoSignin } from "./Redux/Actions/AuthActions"

const App = (props) => {

    useEffect(
        () => {
            auth.onAuthStateChanged(user => {
                if (user) {
                    props.autoSignin(user.uid)
                }

            })
        }, []
    )

    return (
        <Router>
            <Switch>
                <ProtectedRoute loggedin={props.auth.loggedin} exact path="/dashboard" component={Dashboard}></ProtectedRoute>
                <Route exact path="/"><Login /></Route>
                <ProtectedRoute loggedin={props.auth.loggedin} exact path="/profile" component={Profile}></ProtectedRoute>
                <ProtectedRoute loggedin={props.auth.loggedin} exact path="/emergency" component={Emergency}></ProtectedRoute>
                <ProtectedRoute loggedin={props.auth.loggedin} exact path="/notices" component={Notice}></ProtectedRoute>
                <ProtectedRoute loggedin={props.auth.loggedin} exact path="/complains" component={Complains}><Complains /> </ProtectedRoute>
                <ProtectedRoute loggedin={props.auth.loggedin} exact path="/meetings" component={Meetings} ></ProtectedRoute>
            </Switch>
        </Router>
    )
}

const mapStateToProps = (state) => {
    return {
        auth: state.auth
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        autoSignin: (uid) => dispatch(autoSignin(uid))
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(App)

1voto

justdvl Points 310

Je ne modifierai pas votre code, je me contenterai d'expliquer le principe de base : Pendant le rendu de votre route protégée, vous avez 2 options :

Soit vous attendez que l'authentification soit résolue (props.auth.loggedin est true ou false, mais pas undefined - en supposant que vous recevez ces valeurs de BE). En attendant, affichez un écran de chargement. Quand cela est résolu, vous montrez votre page, ou vous redirigez vers Log in.

La deuxième option consiste à aller de l'avant et à commencer à rendre la route privée (protégée). L'utilisateur ne verra pas de données privées, car celles-ci proviennent du backend, et ces appels au backend sont également protégés par une authentification sur le backend. Cette approche vous permettra de commencer directement le rendu du contenu de la route protégée, et pendant ce temps, attendez que props.auth.loggedin arrive du backend - dans votre composant App, configurez React.useEffect en écoutant props.auth.loggedin. Si l'utilisateur n'est pas authentifié, vous le redirigez vers la page de connexion. S'il l'est, rien ne change (ou vous pouvez faire en sorte que votre gestion d'état le sache également).

J'inclus la façon dont je le fais dans mon code pour votre inspiration :

export const AppRoute: React.FC<RouteProps> = observer((props: RouteProps) => {
const { user } = useMst();
const { component, ...rest } = props;
if (!user.isAuthenticated) {
  return <Redirect to={"/login"} />;
}

const Component = component as any;

return (
  <Route
    {...rest}
    render={(props) => (
      <Layout>
        <Component {...props} />
      </Layout>
    )}
  />
);
});

Dans ce code, cependant, je stocke des informations sur l'authentification de l'utilisateur dans le Mobex, et j'écoute les changements d'état du Mobex - ainsi, lorsque le Mobex se rendra compte que l'utilisateur n'est pas authentifié, il déclenchera l'exécution de cette instruction de redirection.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X