• React+AntdUi实现《好客租房系统》我的页面07


    功能分析
    判断是否登录(本地缓存中是否有token信息,直接调用isAuth() 方法即可,这里在utils/auth.js文件中已经封装好了)
    如果登录了,就发送请求获取个人资料,并且在页面中展示个人资料
    如果没有登录,则不获取个人资料,只在页面中展示未登录信息
    在页面中展示登录或未登录信息,就要通过state变化来体现,因此,需要一个标示是否登录的状态

    //判断用户是否登陆步骤
    //在state中添加两个状态:isLogin(是否登录)和userInfo(用户信息)
    state = {
    // 是否登录
    isLogin: isAuth(),
    // 用户信息
    userInfo: {
    avatar: '',
    nickname: ''
    }
    }
    
    //创建方法getUserInfo,用户来获取个人资料
    async getUserInfo() {
    ...
    }
    
    在方法中,通过isLogin判断用户是否登录
    if (!this.state.isLogin) {
    // 未登录
    return
    }
    

     

    如果没有登录,则不发送请求,渲染未登录信息
    // 对用结构使用状态来判断显示登录还是未登录UI
    {/* 登录后展示: */}
    {isLogin ? (
    <>
    <div className={styles.auth}>
    <span onClick={this.logout}>退出</span>
    </div>
    <div className={styles.edit}>
    编辑个人资料
    <span className={styles.arrow}>
    <i className="iconfont icon-arrow" />
    </span>
    </div>
    </>
    ) : (
    <div className={styles.edit}>
    <Button
    type="primary"
    size="small"
    inline
    onClick={() => history.push('/login')}
    >
    去登录
    </Button>
    </div>
    )}

    如果已登录,就根据接口发送请求,获取用户个人资料
    渲染个人资料数据

    async getUserInfo() {
    if (!this.state.isLogin) {
    // 未登录
    return
    }
    
    // 发送请求,获取个人资料
    const res = await API.get('/user', {
    headers: {
    authorization: getToken()
    }
    })
    
    if (res.data.status === 200) {
    // 请求成功
    const { avatar, nickname } = res.data.body
    this.setState({
    userInfo: {
    avatar: BASE_URL + avatar,
    nickname
    }
    })
    }
    }
    
    
    // render方法中
    render(){
    const { history } = this.props
    
    const {
    isLogin,
    userInfo: { avatar, nickname }
    } = this.state
    return (
    <div className={styles.root}>
    {/* 个人信息 */}
    <div className={styles.title}>
    <img
    className={styles.bg}
    src={BASE_URL + '/img/profile/bg.png'}
    alt="背景图"
    />
    <div className={styles.info}>
    <div className={styles.myIcon}>
    <img
    className={styles.avatar}
    src={avatar || DEFAULT_AVATAR}
    alt="icon"
    />
    </div>
    <div className={styles.user}>
    <div className={styles.name}>{nickname || '游客'}</div>
    ...
    }
    

      

    退出功能
    点击退出按钮,弹出对话框,提示是否确定退出
    给退出按钮绑定点击事件,创建方法logout作为事件处理函数
    在退出按钮的事件处理程序中,先调用退出接口(让服务器端退出),再移除本地token(本地退出)
    把登录状态isLogin设置为false,清空用户状态对象
    

      

    {
    text: '退出',
    onPress: async () => {
    // 调用退出接口
    await API.post('/user/logout', null, {
    headers: {
    authorization: getToken()
    }
    })
    
    // 移除本地token
    removeToken()
    
    // 处理状态
    this.setState({
    isLogin: false,
    userInfo: {
    avatar: '',
    nickname: ''
    }
    })
    }
    }
    登录访问控制
    目标
    理解访问控制中的两种功能和两种页面
    能够说出处理两种功能用什么方式来实现
    能够写出 axios请求拦截器与响应拦截器,并且能够说出这两种拦截器分别在什么时候触发,有什么作用
    能够说出处理两种页面用什么方式来实现
    能够说出AuthRoute 鉴权路由组件实现思路
    能够参照官网自己封装AuthRoute 鉴权路由组件
    能够实现修改登录成功后的跳转
    概述
    项目中的两种类型的功能和两种类型的页面:
    
    两种功能:
    
    登录后才能进行操作(比如:获取个人资料)
    不需要登录就可以操作(比如:获取房屋列表)
    两种页面:
    
    需要登录才能访问(比如:发布房源页)
    不需要登录即可访问(比如:首页)
    

      

    对于需要登录才能操作的功能使用 axios 拦截器 进行处理(比如:统一添加请求头 authorization等)

    对于需要登录才能访问的页面使用 路由控制功能处理-使用axios拦截器统一处理token,在api.js 中,添加请求拦截器 (API.interceptors.request.user())。获取到当前请求的接口路径(url)

    判断接口路径,是否是以/user 开头,并且不是登录或注册接口(只给需要的接口添加请求头)如果是,就添加请求头Authorization

    / 添加请求拦截器
    API.interceptors.request.use(config => {
    const { url } = config
    // 判断请求url路径
    if (
    url.startsWith('/user') &&
    !url.startsWith('/user/login') &&
    !url.startsWith('/user/registered')
    ) {
    // 添加请求头
    config.headers.Authorization = getToken()
    }
    return config
    })
    
    添加响应拦截器 (API.interceptors.response.use())
    判断返回值中的状态码
    如果是400,标示token超时或异常,直接移除token
    // 添加响应拦截器
    API.interceptors.response.use(response => {
    const { status } = response.data
    if (status === 400) {
    // 此时,说明 token 失效,直接移除 token 即可
    removeToken()
    }
    return response
    })
    

      


    页面处理-AuthRoute鉴权路由组件

    封装AuthRoute鉴权路由组件在components目录中创建AuthRoute/index.js 文件
    创建组件AuthRoute并导出,在AuthRoute组件中返回Route组件(在Route基础上做了一层包装,用于实现自定义功能)
    给Route组件,添加render方法,指定改组件要渲染的内容(类似与component属性)
    在render方法中,调用isAuth() 判断是否登陆,如果登陆了,就渲染当前组件(通过参数component获取到要渲染的组件,需要重命名)
    如果没有登陆,就重定向到登陆页面,并且指定登陆成功后腰跳转的页面路径
    将AuthRoute组件接收到的props原样传递给Route组件(保证与Route组件使用方式相同),使用AuthRoute组件配置路由规则,验证是否实现页面的登陆访问控制

    const AuthRoute = ({ component: Component, ...rest }) => {
      console.log('rest', rest)
      return (
        <Route
          {...rest}
          render={props => {
            const isLogin = isAuth()
    
            if (isLogin) {
              // 已登录
              // 将 props 传递给组件,组件中才能获取到路由相关信息
              return <Component {...props} />
            } else {
              // 未登录
              return (
                <Redirect
                  to={{
                    pathname: '/login',
                    state: {
                      backUrl: props.location
                    }
                  }}
                />
              )
            }
          }}
        />
      )
    }
    
    export default AuthRoute

    修改登录成功跳转
    登陆成功后,判断是否需要跳转到用户想要访问的页面(判断props.location.state 是否有值)
    如果不需要,则直接调用history.go(-1) 返回上一页
    如果需要,就跳转到from.pathname 指定的页面(推荐使用replace方法模式,不是push)

    // 表单的提交事件
    handleSubmit: async (values, { props }) => {
    ...
    if (status === 200) {
    // 登录成功
    localStorage.setItem('hkzf_token', body.token)
    
    /*
    1 登录成功后,判断是否需要跳转到用户想要访问的页面(判断 props.location.state 是否有值)。
    2 如果不需要(没有值),则直接调用 history.go(-1) 返回上一页。
    3 如果需要,就跳转到 from.pathname 指定的页面(推荐使用 replace 方法模式,而不是 push)。
    */
    if (!props.location.state) {
    // 此时,表示是直接进入到了该页面,直接调用 go(-1) 即可
    props.history.go(-1)
    } else {
    // replace: [home, map]
    props.history.replace(props.location.state.from.pathname)
    }
    } else {
    // 登录失败
    Toast.info(description, 2, null, false)
    }
    }
    

      

    本文参考自:https://blog.csdn.net/weixin_45583708/article/details/103327917

  • 相关阅读:
    WebSocket理解与使用
    JS面向对象与prototype,__proto__,constructor
    JS值传递与引用传递
    vue报错:./node_modules/babel-loader/lib!./node_modules/vue-loader/lib/selector.js?type=script&index=0!
    对于图片视频编辑类产品的思考
    时尚衣裙外贸独立站搭建(一)
    2021年Wordpress手把手教你做个独立站——部署篇
    一次备案失败所引发的思考
    2021年Wordpress博客装修美化(二)
    做什么,怎么做?(20210615)
  • 原文地址:https://www.cnblogs.com/wmlcn/p/15083093.html
Copyright © 2020-2023  润新知