0
我嘗試將用戶重新路由到用戶試圖在瀏覽器地址欄上導航的url: 我檢查用戶是否登錄調用服務方法。如果cookie中的會話過期或無效,則返回401個狀態,我會重定向到登錄界面React組件渲染不是第一次用redux
如果用戶已登錄,允許。
如果用戶沒有登錄,路線登錄畫面和登錄後,路線所需的URL。
這裏的問題是,當用戶鍵入一個網址,如:http://url/app/order 它被重定向到登錄網址: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>
);
}
}
LoginContainer
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
}
}
的用戶數據服務被調用一次刷新瀏覽器,我不希望把它在localStorage的,因爲瀏覽器被刷新時,我不希望用戶看到任何東西,如果會話過期o是無效的時候。反正我在我的崗位問題是,爲什麼AutjorizedRoute組件的渲染方法不叫登陸之後的第一時間,而是再次點擊登錄按鈕時的作品。 – Fadd