简易的登录系统制作

175 阅读2分钟

在对vue框架学习的比较熟练之后,我开始尝试尝试使用react框架来实现一些新的项目。这篇文章主要是断更这些天里,从最近写的项目里的总结,实现的是基于react umi 搭建的管理系统。

登录系统

凡是一个完整的系统一定具有的功能就是登录了。目前大多数网站都是区分用户权限的,最常见的就是视频网站里面的VIP用户和普通用户,某些特定的网页也只有对应身份的用户才开放。登录系统最基础的功能就是可以把用户划分成不同类型。

在用户访问我的网页时,首先会出现的是登录页面。用户在登录时提供了两种登录方式账号密码登录手机验证码登录

在用户登录成功之后,就会接收到后端返回的token字段,采用sessionStorage将字段保存到本地并设置一个全局变量来保存用户的信息。

首先基于umi的fetch封装一个HTTP类来完成后端接口请求操作

class HTTP {
  static async staticFetch(url = '', options = {}) {
    url = "/api" + url;
    // 声明默认的配置信息
    const defaultOptions = {
      mode: "cors",
      headers: {
        token: sessionStorage.getItem('token') || null,
      },
    }

    if (options.method === "POST" || options.method === "PUT") {
      defaultOptions.headers['Content-type'] = "application/json;charset=utf-8";
    }

    const newOptions = { ...defaultOptions, ...options };
    
    // 可以封装一些方法来完善不同的请求情况
    return fetch(url, newOptions).then(res => {
      const token = res.headers.get('token');
      token && sessionStorage.setItem('token', token);
      return res.json()
    }).catch(handlerError)

  }
  get(url, option = {}) {
    const options = Object.assign({ method: 'GET' }, option);
    Object.keys(options) && (url += '?' + qs.stringify(option))
    return HTTP.staticFetch(url, options)
  }
  post(url, params = {}, option = {}) {
    const options = Object.assign({ method: 'POST' }, option);
    options.body = JSON.stringify(params);
    return HTTP.staticFetch(url, options)
  }
}

开启一个全局的 model 储存用户信息

 {
  namespace: 'user',
  state: {
    userInfo: sessionStorage.getItem('userProfile') ? JSON.parse(sessionStorage.getItem('userProfile')) : null
  },
  reducers: {
    updateUserProfile: (state, {payload}) => ({
      ...state,
      ...payload
    })
  },
  effects: {
    *login({ payload }, { put, call, select }) {
      const { data, mes } = yield call($http.userLogin, payload);
      if (!data) {
        message.error(mes)
        return
      }
      sessionStorage.setItem('userProfile', data);
      yield put({
        type: 'updateUserProfile',
        payload: {userInfo: data}
      })
    }
  }
}

路由守卫

在平时我们逛淘宝的时候,当你点击了购买按钮的时候,你会发现弹出的不是订单界面而是切换到了登录页面。没有用户信息就无法涉及到商品系列的操作,这种情况是非常符合逻辑的。这时候所涉及到的就是路由守卫,他的原理就是网页的路由跳转拦截。

umi框架中是基于sunscriptions事件派发实现。在全局model里处理

{
  namespace: 'common',
  state: {

  },
  subscriptions: {
    setup({dispatch, history}){
      // 初始化查询用户是否登录, app.start阶段进行执行
      dispatch({type: 'queryUserLogin', payload: {history}})
    },
  },
  effects: {
    *queryUserLogin({payload}, {put, call}){
      // 判断用户当前访问的路径
      const {history, history: {location: {pathname}}} = payload;

      if(pathname !== '/users/login'){

        // 处理登录信息
        if(!sessionStorage.getItem('userProfile') || !sessionStorage.getItem('token') || !sessionStorage.getItem('routeList')){
          history.replace('/users/login');
        }else{
          // 用户满足条件还需进行信息验证
          const res = yield call($http.queryUserLogin);
          if (res.code !== 0) {
            return;
          }
          // 路由表由接口获取
          const {data: routeList} = yield call($http.getRouteList);
          sessionStorage.setItem('routeList', JSON.stringify(routeList));
        }
      }else{
        // 非拦截页面
        sessionStorage.clear();
      }
    }
  }
}