加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

reactjs – react-boilerplate authentication登录页面在页面重

发布时间:2020-12-15 20:32:06 所属栏目:百科 来源:网络整理
导读:我正在开发一个带有登录页面和应用程序其余页面的应用程序(应登录查看).我正在使用 react-boilerplate .从这个 example ,我编辑了我的asyncInjectors.js文件,以获得redirectToLogin和redirectToDashboard方法: //asyncInjectors.jsexport function redirect
我正在开发一个带有登录页面和应用程序其余页面的应用程序(应登录查看).我正在使用 react-boilerplate.从这个 example,我编辑了我的asyncInjectors.js文件,以获得redirectToLogin和redirectToDashboard方法:

//asyncInjectors.js
export function redirectToLogin(store) {
  return (nextState,replaceState) => {
    const isAuthenticated = store.getState().get('app').get('isAuthenticated');

    if (!isAuthenticated) {
      replaceState({
        pathname: '/login',state: {
          nextPathname: nextState.location.pathname,},});
    }
  };
}

export function redirectToDashboard(store) {
  return (nextState,replaceState) => {
    const isAuthenticated = store.getState().get('app').get('isAuthenticated');

    if (isAuthenticated) {
      replaceState('/');
    }
  }
}

然后我只将redirectToLogin设置为页面的onEnter,并将redirectToDashboard设置为登录页面.

它工作正常,但在登录时页面刷新(F5)时,登录页面会短暂呈现,然后呈现实际页面.登录页面只在componentWillMount中调度验证操作,然后在componentDidUpdate中重定向:

//login.js
componentWillMount() {
  this.props.dispatch(authenticate());
}

componentDidUpdate(prevProps,prevState) {
  if (this.props.isAuthenticated) {
    const nextPathname = prevProps.location.state ? prevProps.location.state.nextPathname : '/';

    browserHistory.push(nextPathname);
  }
}

页面的容器也具有相同的componentWillMount代码.不确定是不是因为传奇,但这里是代码:

//sagas.js
export function* login({ user,password }) {
    try {
        const token = yield call(app.authenticate,{
            strategy: 'local',user,password,});

        return token;
    } catch (error) {
        return onError(error);
    }
}

// For page refresh after logging in
export function* authenticate() {
    try {
        const token = yield call(app.authenticate);

        return token;
    } catch (error) {
        return onError(error);
    }
}

export function* logout() {
    try {
        const response = yield call(app.logout);

        return response;
    } catch (error) {
        return onError(error);
    }
}

export function* loginFlow() {
    while (true) {
        const request = yield take(LOGIN_REQUEST);
        const winner = yield race({
            auth: call(login,request.data),logout: take(LOGOUT_REQUEST),});

        if (winner.auth && winner.auth.accessToken) {
            yield put(actions.setAuthState(true));
        }
    }
}

export function* logoutFlow() {
    while (true) {
        yield take(LOGOUT_REQUEST);
        yield put(actions.setAuthState(false));
        yield call(logout);
        browserHistory.push('/login');
    }
}

export function* authenticateFlow() {
    while (true) {
        yield take(AUTHENTICATE);

        const response = yield call(authenticate);

        if (response && response.accessToken) {
            yield put(actions.setAuthState(true));
        }
    }
}

export default [
    loginFlow,logoutFlow,authenticateFlow,];

如何摆脱闪烁的登录页面?

编辑:
当我尝试gouroujo的答案时,我无法注销.

//asyncInjectors.js
import jwtDecode from 'jwt-decode';

export function redirectToLogin(store) {
    return (nextState,replaceState,callback) => {
        const token = localStorage.token;

        if (token) {
            const jwt = jwtDecode(token);

            if (jwt.exp <= (new Date().getTime() / 1000)) {
                store.dispatch(actions.setAuthState(false));

                replaceState({
                    pathname: '/login',state: {
                        nextPathname: nextState.location.pathname,});
            }
        }

        store.dispatch(actions.setAuthState(true));
        callback();
    };
}

当我点击刷新时,登录页面没有显示,但现在我无法注销.

解决方法

您有两种方法可以避免在初始渲染时刷新登录页面:使您的身份验证功能同步或等待加载页面的答案.

1-检查您的令牌是否存在且有效(到期日期)客户端,以选择是否必须首先将用户重定向到登录或仪表板页面.当答案从您的服务器返回时,您可以更正您的初始猜测,但在大多数情况下您不需要.

用户登陆 – >

>检查令牌客户端 – >如果需要,重定向到登录
>检查令牌服务器端 – >等待回答 – >如果需要,重新定向

要检查令牌客户端,您必须检查本地存储.例如:

class App extends Component {
  requireAuth = (nextState,replace) => {
    if (!localStorage.token) {
      replace({
        pathname: '/login',state: { nextPathname: nextState.location.pathname }
      })
    }
  }
  render() {
    return (
      <Router history={browserHistory}>
        <Route path="/login" component={LoginPage} />
        <Route
          path="/"
          component={AppLayout}
          onEnter={this.requireAuth}
        > ... </Route>
     )
   }
 }

如果您使用具有相对较短的到期日期的令牌,则还必须检查到期日期,从而解码令牌.

try {
      const jwt = JWTdecode(token);
      if (moment().isBefore(moment.unix(jwt.exp))) {
        return nextState;
      } else {
       replace({
        pathname: '/login',state: { nextPathname: nextState.location.pathname }
       })
      }
    } catch (e) {
      replace({
        pathname: '/login',state: { nextPathname: nextState.location.pathname }
      })
    }

2-在从服务器收到答案之前显示加载屏幕.在不透明度上添加一些Css过渡效果以避免“闪光”

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读