Я тарирую аутентификацию в React с помощью Laravel API, и все работает отлично, за исключением некоторых проблем с маршрутизатором.
Я условно делаю перенаправление следующим образом:
if (this.state.redirect) {
return <Redirect to = "/home" />;
}
const login = localStorage.getItem("isLoggedIn");
if (login) {
return <Redirect to = "/home" />;
}
App.js
export default class App extends Component {
render() {
let navLink = (
<div className = "Tab">
<NavLink to = "/sign-in" activeClassName = "activeLink" className = "signIn">
Sign In
</NavLink>
<NavLink exact to = "/" activeClassName = "activeLink" className = "signUp">
Sign Up
</NavLink>
</div>
);
const login = localStorage.getItem("isLoggedIn");
return (
<div className = "App">
{login ? (
<Router>
<Route exact path = "/" component = {Signup}></Route>
<Route path = "/sign-in" component = {Signin}></Route>
<Route path = "/home" component = {Home}></Route>
</Router>
) : (
<Router>
{navLink}
<Route exact path = "/" component = {Signup}></Route>
<Route path = "/sign-in" component = {Signin}></Route>
<Route path = "/home" component = {Home}></Route>
</Router>
)}
</div>
);
}
}
Вход.js
export default class Signin extends Component {
constructor(props) {
super(props);
this.state = {
email: "",
password: "",
msg: "",
isLoading: false,
redirect: false,
errMsgEmail: "",
errMsgPwd: "",
errMsg: "",
};
}
onChangehandler = (e) => {
let name = e.target.name;
let value = e.target.value;
let data = {};
data[name] = value;
this.setState(data);
};
onSignInHandler = () => {
this.setState({ isLoading: true });
axios
.post("http://localhost:8000/api/user-login", {
email: this.state.email,
password: this.state.password,
})
.then((response) => {
this.setState({ isLoading: false });
if (response.data.status === 200) {
localStorage.setItem("isLoggedIn", true);
localStorage.setItem("userData", JSON.stringify(response.data.data));
this.setState({
msg: response.data.message,
redirect: true,
});
}
if (
response.data.status === "failed" &&
response.data.success === undefined
) {
this.setState({
errMsgEmail: response.data.validation_error.email,
errMsgPwd: response.data.validation_error.password,
});
setTimeout(() => {
this.setState({ errMsgEmail: "", errMsgPwd: "" });
}, 2000);
} else if (
response.data.status === "failed" &&
response.data.success === false
) {
this.setState({
errMsg: response.data.message,
});
setTimeout(() => {
this.setState({ errMsg: "" });
}, 2000);
}
})
.catch((error) => {
console.info(error);
});
};
render() {
if (this.state.redirect) {
return <Redirect to = "/home" />;
}
const login = localStorage.getItem("isLoggedIn");
if (login) {
return <Redirect to = "/home" />;
}
const isLoading = this.state.isLoading;
return (
<div>
<Form className = "containers">
<FormGroup>
<Label for = "email">Email id</Label>
<Input
type = "email"
name = "email"
placeholder = "Enter email"
value = {this.state.email}
onChange = {this.onChangehandler}
/>
<span className = "text-danger">{this.state.msg}</span>
<span className = "text-danger">{this.state.errMsgEmail}</span>
</FormGroup>
<FormGroup>
<Label for = "password">Password</Label>
<Input
type = "password"
name = "password"
placeholder = "Enter password"
value = {this.state.password}
onChange = {this.onChangehandler}
/>
<span className = "text-danger">{this.state.errMsgPwd}</span>
</FormGroup>
<p className = "text-danger">{this.state.errMsg}</p>
<Button
className = "text-center mb-4"
color = "success"
onClick = {this.onSignInHandler}
>
Sign In
{isLoading ? (
<span
className = "spinner-border spinner-border-sm ml-5"
role = "status"
aria-hidden = "true"
></span>
) : (
<span></span>
)}
</Button>
</Form>
</div>
);
}
}
Signup.js
export default class Signup extends Component {
userData;
constructor(props) {
super(props);
this.state = {
signupData: {
name: "",
email: "",
phone: "",
password: "",
isLoading: "",
},
msg: "",
};
}
onChangehandler = (e, key) => {
const { signupData } = this.state;
signupData[e.target.name] = e.target.value;
this.setState({ signupData });
};
onSubmitHandler = (e) => {
e.preventDefault();
this.setState({ isLoading: true });
axios
.post("http://localhost:8000/api/user-signup", this.state.signupData)
.then((response) => {
this.setState({ isLoading: false });
if (response.data.status === 200) {
this.setState({
msg: response.data.message,
signupData: {
name: "",
email: "",
phone: "",
password: "",
},
});
setTimeout(() => {
this.setState({ msg: "" });
}, 2000);
}
if (response.data.status === "failed") {
this.setState({ msg: response.data.message });
setTimeout(() => {
this.setState({ msg: "" });
}, 2000);
}
});
};
render() {
const isLoading = this.state.isLoading;
return (
<div>
<Form className = "containers shadow">
<FormGroup>
<Label for = "name">Name</Label>
<Input
type = "name"
name = "name"
placeholder = "Enter name"
value = {this.state.signupData.name}
onChange = {this.onChangehandler}
/>
</FormGroup>
<FormGroup>
<Label for = "email">Email id</Label>
<Input
type = "email"
name = "email"
placeholder = "Enter email"
value = {this.state.signupData.email}
onChange = {this.onChangehandler}
/>
</FormGroup>
<FormGroup>
<Label for = "phone">Phone Number</Label>
<Input
type = "phone"
name = "phone"
placeholder = "Enter phone number"
value = {this.state.signupData.phone}
onChange = {this.onChangehandler}
/>
</FormGroup>
<FormGroup>
<Label for = "password">Password</Label>
<Input
type = "password"
name = "password"
placeholder = "Enter password"
value = {this.state.signupData.password}
onChange = {this.onChangehandler}
/>
</FormGroup>
<p className = "text-white">{this.state.msg}</p>
<Button
className = "text-center mb-4"
color = "success"
onClick = {this.onSubmitHandler}
>
Sign Up
{isLoading ? (
<span
className = "spinner-border spinner-border-sm ml-5"
role = "status"
aria-hidden = "true"
></span>
) : (
<span></span>
)}
</Button>
<Link to = "/sign-in" className = "text-white ml-5">I'm already member</Link>
</Form>
</div>
);
}
}
Моя проблема в том, что компонент {navLink} по-прежнему отображается в обоих случаях, когда вы вошли в систему или нет!! но когда я обновляю страницу вручную, она идет!
изображения
Я использовал history.push() перед тем, как отправить свой вопрос, и не решил проблему.
можно ли сделать песочницу из ваших кодов? плохо помочь вам исправить это.
Я пытался, но у меня возникли проблемы с тем, что я извиняюсь, новичок в реакции! но я использовал этот туто :programmingfields.com/…
Так позвольте мне сделать это для вас!
это будет мило с твоей стороны :)
проверьте пример из моего ответа.
У меня есть некоторый опыт в этом, поэтому я могу поделиться им с вами, возможно, вам это поможет.
Сделать защищенный рут
export const ProtectedRoute = (props) => {
let redirectPath = "";
if (!localStorage.getItem("isLoggedIn")) {
redirectPath = props.authenticationPath;
}
if (redirectPath) {
const renderComponent = () => <Redirect to = {{ pathname: redirectPath }} />;
return <Route {...props} component = {renderComponent} render = {undefined} />;
} else {
return <Route {...props} />;
}
};
Используйте его так на компоненте маршрутизатора:
<ProtectedRoute
exact
path = "/profile"
component = {Profile}
restrictedPath = "/profile"
authenticationPath = "/login"
/>
После отправки формы входа или регистрации
history.push("/profile")
Я сделал небольшой пример на codeandbox со всем, что вам нужно для начала, надеюсь, это поможет.
спасибо, брат, за твои усилия, я очень ценю тебя!
@WrakAli Нет проблем, братан, рад тебе помочь.
Вы должны использовать
history.push()
после отправки формы для повторного рендеринга, но мой ответ — лучшая идея для создания защищенного маршрута.