我尝试从Login Component重定向到DashBoard Component。
在这种情况下,我的登录组件称为CodeClient,DashBoard组件称为IndexComponent。
我的问题是CodeClient组件发出了使用openid进行身份验证的请求,当它进行回调时它没有输入sendToken(code, status)
,因为它没有获取信息。我想在之前重定向获取代码并提出请求。
如果渲染只包含:
class App extends Component {
render() {
return (
<CodeClient />
);
}
}
export default App;
在sendToken(code, status)
上输入并创建Cookie,然后显示网址:http://localhost:3000/loginCallback?code=ab4d60814c50fe66de0bd9z4a3318f12&session_state=mVnqjmlT4gyTslk0cwbYeSOvxIKHqIl85pPX6Gh7f1c.63dfcdf9691b3ebcdd0cb28dcac27e94
但是,当我试图制作时,我在一秒钟内显示以前的网址,然后对此进行更改:http://localhost:3000/login
我的想法是,用户不应该在没有权限的情况下访问任何路由,并且用户将被验证并在索引页面上继续刷新导航器。
我不确定自己是否表现不错,而且我疯狂地解决问题,getToken
上的输入发出请求,等待,创建Cookie并重定向到索引
谢谢,对不起我的英文
这是我的代码:
App.js
import React, { Component } from 'react';
import { BrowserRouter, Redirect, Switch, Route } from 'react-router-dom';
import './App.css';
import CodeClient from './components/Login/CodeClient';
import IndexComponent from './components/Index/IndexComponent';
const checkAuth = () => {
const cookie = JSON.parse(localStorage.getItem('cookie'));
if (!cookie) return false;
try {
const exp = cookie.exp;
const current = new Date().getTime();
if (exp < current) {
return false;
}
return true;
} catch (error) {
return false;
}
}
const Home = (props) => {
if (checkAuth() === true) {
return <IndexComponent {...props} />
}
return <Redirect to={{
pathname: '/login',
state: { from: props.location }
}} />
}
const PrivateRoute = ({ component: Component, ...rest }) => (
<Route
{...rest}
render={props =>
checkAuth() ? (
<Component {...props} />
) : (
<Redirect
to={{
pathname: "/login",
state: { from: props.location }
}}
/>
)
}
/>
);
class App extends Component {
render() {
return (
<BrowserRouter>
<Switch>
<Route path="/login" component={CodeClient} />
<PrivateRoute path="/" component={Home} />
</Switch>
</BrowserRouter>
);
}
}
export default App;
CodeClient.js
import React, { Component } from 'react';
import './CodeClient.css';
import request from 'request';
class CodeClient extends Component {
constructor(props) {
super(props);
this.state = { messageError: '', ok: false };
this.url = 'https://url_example/connect/authorize?scope=openid&response_type=code&client_id=myclientid&redirect_uri=http://localhost:3000/loginCallback';
this.url = encodeURI(this.url);
}
handleLogin = (event) => {
event.preventDefault();
window.location.href = this.url;
}
componentDidMount() {
var url_string = window.location.href;
var url = new URL(url_string);
var code = url.searchParams.get("code");
var session_state = url.searchParams.get("session_state");
if (code) {
this.sendToken(code, session_state);
}
}
sendToken = (code, state) => {
var options = {
method: 'POST',
url: 'http://localhost:8080/login',
headers: { 'content-type': 'application/json' },
body: {
code: code,
state: state
},
json: true
};
request(options, (error, response, body) => {
if (error) {
this.setState({ messageError: 'Error al autenticarse: ', error, ok: false });
// throw new Error(error);
}
if (body.ok === true) {
this.createCookie(body);
this.props.history.push('/');
} else {
this.setState({ messageError: 'El código ya no sirve', ok: false });
}
});
}
createCookie = (data) => {
var info = {
id: data.id,
name: data.name,
exp: new Date().getTime() + data.expires_in,
};
console.log(info)
localStorage.setItem('cookie', JSON.stringify(info));
}
render() {
return (
<div className="Menu">
<div className="container">
<div className="card card-container">
<img id="profile-img" className="profile-img-card" src="//ssl.gstatic.com/accounts/ui/avatar_2x.png" alt="logo" />
<p id="profile-name" className="profile-name-card"></p>
<form className="form-signin">
{
(this.state.ok === false) ? <span id="reauth-email" className="reauth-email error">{this.state.messageError}</span> :
<span id="reauth-email" className="reauth-email success">{this.state.messageError}</span>
}
<button className="btn btn-lg btn-primary btn-block btn-signin" onClick={this.handleLogin} >Conectar</button>
</form>
</div>
</div>
</div>
);
}
}
export default CodeClient;
答案 0 :(得分:0)
这是一种可能的解决方案,但这是一个糟糕的解决方案或实施不好。
App.js
import React, { Component } from 'react';
import './App.css';
import request from 'request';
import IndexComponent from './components/Index/IndexComponent';
const checkAuth = () => {
const cookie = JSON.parse(localStorage.getItem('cookie'));
if (!cookie) return false;
try {
const exp = cookie.exp;
const current = new Date().getTime();
if (exp < current) {
return false;
}
return true;
} catch (error) {
return false;
}
}
class App extends Component {
constructor(props) {
super(props);
// window.history.pushState("", "", '/');
this.state = { logged: false, messageError: '', ok: false };
this.url = 'https://url_example/connect/authorize?scope=openid&response_type=code&client_id=myclientid&redirect_uri=http://localhost:3000/loginCallback';
this.url = encodeURI(this.url);
}
handleLogin = (event) => {
event.preventDefault();
window.location.href = this.url;
}
componentDidMount() {
var url_string = window.location.href;
var url = new URL(url_string);
var code = url.searchParams.get("code");
var session_state = url.searchParams.get("session_state");
if (code) {
this.sendToken(code, session_state);
}
}
sendToken = (code, state) => {
var options = {
method: 'POST',
url: 'http://localhost:8080/login',
headers: { 'content-type': 'application/json' },
body: {
code: code,
state: state
},
json: true
};
request(options, (error, response, body) => {
if (error) {
this.setState({ messageError: 'Error al autenticarse: ', error, ok: false });
// throw new Error(error);
}
if (body.ok === true) {
this.createCookie(body);
} else {
this.setState({ messageError: 'El código ya no sirve', ok: false });
}
});
}
createCookie = (data) => {
var info = {
id: data.id,
name: data.name,
exp: new Date().getTime() + data.expires_in,
};
localStorage.setItem('cookie', JSON.stringify(info));
this.setState({ logged: true });
}
render() {
if (checkAuth()) return <IndexComponent />;
else {
return (
<div className="Menu">
<div className="container">
<div className="card card-container">
<img id="profile-img" className="profile-img-card" src="//ssl.gstatic.com/accounts/ui/avatar_2x.png" alt="logo" />
<p id="profile-name" className="profile-name-card"></p>
<form className="form-signin">
{
(this.state.ok === false) ? <span id="reauth-email" className="reauth-email error">{this.state.messageError}</span> :
<span id="reauth-email" className="reauth-email success">{this.state.messageError}</span>
}
<button className="btn btn-lg btn-primary btn-block btn-signin" onClick={this.handleLogin} >Conectar</button>
</form>
</div>
</div>
</div>
);
}
}
}
export default App;
IndexComponent.js
import React, { Component } from 'react';
import './IndexComponent.css'
const checkAuth = () => {
const cookie = JSON.parse(localStorage.getItem('cookie'));
if (!cookie) return false;
try {
const exp = cookie.exp;
const current = new Date().getTime();
if (exp < current) {
return false;
}
return true;
} catch (error) {
return false;
}
}
class IndexComponent extends Component {
constructor(props) {
super(props);
window.history.pushState("", "", '/menu');
this.checkCookie();
}
checkCookie = () => {
if (!checkAuth()) {
this.logout();
}
}
logout = () => {
localStorage.setItem('cookie', null);
window.location.href = '/';
}
render() {
return (
<div>
<h1>Home!</h1>
<p>Estas logueado! Muy bien!</p>
<button onClick={() => {
this.logout()
}}>Cerrar sesión</button>
</div>
);
}
}
export default IndexComponent;