【发布时间】:2017-09-25 21:46:56
【问题描述】:
我正在尝试通过执行以下操作将用户重新路由到用户尝试在浏览器地址栏上导航的 url: 我通过调用服务方法检查用户是否登录。如果 cookie 中的 session 过期或者无效,会返回 401 状态,我会重定向到登录界面
如果用户已登录,则允许。
如果用户未登录,则路由到登录屏幕,登录后,路由到所需的 url。
这里的问题是,当用户输入如下网址时:http://url/app/order 它被重定向到登录 URL:http://url/auth/login 在用户输入他的凭据后,虽然操作被调度,但 Authorizedroute 组件的渲染不会被调用。在我再次点击登录按钮后它会被调用。
以下是我的登录组件
export class LoginForm extends React.Component {
componentWillReceiveProps(newProps){
const { location, isAuthenticated, history } = newProps;
if(isAuthenticated){
if(location.state && location.state.referrer){
history.push(location.state.referrer.pathname);
}else{
history.replace('/app');
}
}
}
render() {
let usernameInput, passwordInput;
const { showErrorMessage, errorMessage, onLogin } = this.props;
return (
<div className='sme-login-center-view-container'>
<HeaderComponent />
<Col lg={4} lgOffset={4} sm={12} xs={12}>
<Col lg={10} lgOffset={2} sm={4} smOffset={4}>
<Form className="sme-login-box" onSubmit={(e)=> {
e.preventDefault();
let creds = {username: usernameInput.value, password: passwordInput.value};
onLogin(creds);
}
}>
<span className='text-center sme-login-title-text'><h4>User Login</h4></span>
<FormGroup >
{errorMessage ? (<Alert bsStyle="danger"><strong>Error!</strong> {errorMessage}</Alert>) : null }
</FormGroup>
<FormGroup controlId="formHorizontalUsername">
<FormControl type="username" placeholder="Username" bsStyle="form-rounded"
inputRef={(ref) => {usernameInput = ref}}
/>
<FormControl.Feedback>
<span className="fa fa-user-o sme-login-input-feedback-span"></span>
</FormControl.Feedback>
</FormGroup>
<FormGroup controlId="formHorizontalPassword">
<FormControl type="password" placeholder="Password"
inputRef={(ref) => {passwordInput = ref}}/>
<FormControl.Feedback>
<span className="fa fa-lock sme-login-input-feedback-span"></span>
</FormControl.Feedback>
</FormGroup>
<FormGroup>
<Button type="submit" block >Login</Button>
</FormGroup>
</Form>
</Col>
</Col>
</div>
);
}
}
登录容器
const mapStateToProps = state => {
return state.authenticationReducer.login
}
export const Login = withRouter(connect( mapStateToProps,{ onLogin: loginUser })(LoginForm))
登录操作
export function requestLogin(creds) {
return {
type: LOGIN_REQUEST,
isFetching: true,
isAuthenticated: false,
creds
}
}
export function receiveLogin() {
return {
type: LOGIN_SUCCESS,
isFetching: false,
isAuthenticated: true
}
}
export function loginError(message) {
return {
type: LOGIN_FAILURE,
isFetching: false,
isAuthenticated: false,
errorMessage: message
}
}
export function loginUser(creds) {
return dispatch => {
dispatch(requestLogin(creds))
return axios.post(url, data)
.then(response => {
if (!response.status === 200) {
dispatch(loginError(response.statusText))
} else {
dispatch(receiveLogin())
}
}
).catch(function (error) {
dispatch(loginError(error.response.statusText))
}
) }
}
登录缩减器:
export function login(state = {
isFetching: false,
isAuthenticated: false
}, action) {
switch (action.type) {
case LOGIN_REQUEST:
case LOGIN_SUCCESS:
case LOGIN_FAILURE:
return Object.assign({}, state, action)
default:
return state
}
}
授权路由组件
class AuthorizedRouteComponent extends React.Component {
componentWillMount() {
this.props.getUser();
}
render() {
const { component: Component, pending, logged, location, ...rest } = this.props;
return (
<Route {...rest} render={props => {
if (pending) return <div>Loading...</div>
return logged
? <Component {...this.props} />
:<Redirect to={{
pathname: '/auth/login',
state: { referrer: location }
}}/>
}} />
)
}
}
const mapStateToProps = state => {
return state.authenticationReducer.loggedUser
}
const AuthorizedRoute = connect(mapStateToProps, { getUser: getLoggedUser })(AuthorizedRouteComponent);
export default AuthorizedRoute
查找记录的用户操作
export function requestFetch() {
return {
type: FETCH_REQUEST,
pending: true,
logged: false
}
}
export function receiveFetch(userData) {
return {
type: FETCH_SUCCESS,
pending: false,
logged: true,
userData
}
}
export function fetchError(message) {
return {
type: FETCH_FAILURE,
pending: false,
logged: false,
errorMessage:message
}
}
export function getLoggedUser() {
return dispatch => {
dispatch(requestFetch())
return axios.get('/o3/rest/user/userdetails')
.then(response => {
if (!response.status === 200) {
dispatch(fetchError(response.statusText))
} else {
dispatch(receiveFetch(response.data))
}
}
).catch(function (error) {
dispatch(fetchError(error.response.statusText))
}
)
}
}
最后是我的登录用户减速器
export function loggedUser(state = initialState, action) {
switch (action.type) {
case FETCH_REQUEST:
case FETCH_SUCCESS:
case FETCH_FAILURE:
let obj = Object.assign({}, state, action);
return obj;
default:
return state
}
}
【问题讨论】:
标签: reactjs redux react-router-v4