Javascript JS:如何通过重定向函数将url传递给登录函数

Javascript JS:如何通过重定向函数将url传递给登录函数,javascript,node.js,reactjs,redirect,next.js,Javascript,Node.js,Reactjs,Redirect,Next.js,在我的React/nextJS应用程序中,我正在检查getInitialProps静态函数中的有效令牌。 我把它当作一个临时的,但在这种情况下,这不重要 如果令牌无效(或丢失),用户将被重定向到登录页面。这是通过如下所示的重定向功能完成的。到目前为止,一切顺利 我如何传递用户重定向到登录组件的页面的url 如果用户没有登录并且正在调用类似的东西,他将被重定向到索引页():将有一个登录表单。如果登录成功,我想将他重定向回第一个调用的页面: 以未登录用户身份调用受限页面 重定向到索引登录页面 登录后

在我的React/nextJS应用程序中,我正在检查
getInitialProps
静态函数中的有效令牌。 我把它当作一个临时的,但在这种情况下,这不重要

如果令牌无效(或丢失),用户将被重定向到登录页面。这是通过如下所示的
重定向
功能完成的。到目前为止,一切顺利

我如何传递用户重定向到登录组件的页面的url

如果用户没有登录并且正在调用类似的东西,他将被重定向到索引页():将有一个登录表单。如果登录成功,我想将他重定向回第一个调用的页面:

  • 以未登录用户身份调用受限页面
  • 重定向到索引登录页面
  • 登录后重定向回第页,共1页
  • 我不知道如何将此信息传递到登录函数

    使用服务器props.js

    export default WrappedComponent =>
      class extends Component {
        static async getInitialProps (context) {
          const { req, pathname } = context
          let isValid = false
    
          if (req && req.headers) {
            const cookies = req.headers.cookie
            if (typeof cookies === 'string') {
              const cookiesJSON = jsHttpCookie.parse(cookies)
              initProps.token = cookiesJSON['auth-token']
              if (cookiesJSON['auth-token']) {
                jwt.verify(cookiesJSON['auth-token'], secret, (error, decoded) => {
                  if (error) {
                    console.error(error)
                  } else {
                    isValid = true
                  }
                })
              }
            }
          }
    
          // Redirect to index (=login) page if isValid is false
          if (!isValid && pathname && pathname !== '/') {
            redirect(context, pathname ? '/?ref=' + pathname : '/')
          }
    
          return initProps
        }
        render () {
          return <WrappedComponent {...this.props} />
        }
      }
    
    import Router from 'next/router'
    
    export default (context, target) => {
      if (context.res) {
        // server
        context.res.writeHead(303, { Location: target })
        context.res.end()
      } else {
        // In the browser, we just pretend like this never even happened ;)
        Router.replace(target)
      }
    }
    
    页面/index.js

    export default WrappedComponent =>
      class extends Component {
        static async getInitialProps (context) {
          const { req, pathname } = context
          let isValid = false
    
          if (req && req.headers) {
            const cookies = req.headers.cookie
            if (typeof cookies === 'string') {
              const cookiesJSON = jsHttpCookie.parse(cookies)
              initProps.token = cookiesJSON['auth-token']
              if (cookiesJSON['auth-token']) {
                jwt.verify(cookiesJSON['auth-token'], secret, (error, decoded) => {
                  if (error) {
                    console.error(error)
                  } else {
                    isValid = true
                  }
                })
              }
            }
          }
    
          // Redirect to index (=login) page if isValid is false
          if (!isValid && pathname && pathname !== '/') {
            redirect(context, pathname ? '/?ref=' + pathname : '/')
          }
    
          return initProps
        }
        render () {
          return <WrappedComponent {...this.props} />
        }
      }
    
    import Router from 'next/router'
    
    export default (context, target) => {
      if (context.res) {
        // server
        context.res.writeHead(303, { Location: target })
        context.res.end()
      } else {
        // In the browser, we just pretend like this never even happened ;)
        Router.replace(target)
      }
    }
    
    在index.js上有
    submit
    功能来登录用户。此时,应将用户重定向到初始页面:

    _onSubmit (event) {
      this.props.loginMutation({
        variables: { username, password }
      }).then(response => {
        const token = response.data.token
        if (token) {
          Cookies.set('auth-token', token, { expires: 1 })
          this.props.client.resetStore().then(() => {
            window.location.assign('/') // <-- Redirect to initial called page
          })
        }
      })
    }
    
    \u提交(事件){
    this.props.loginMutation({
    变量:{用户名,密码}
    })。然后(响应=>{
    const token=response.data.token
    如果(令牌){
    set('auth-token',token,{expires:1})
    this.props.client.resetStore()。然后(()=>{
    
    window.location.assign(“/”)/您需要的是
    react router
    或更具体地说是
    react router dom
    包。如果您了解它的工作方式,这将是一件轻而易举的事

    对于您的场景,在未进行身份验证时,您可以使用
    ,而不是调用
    重定向()
    。这会自动替换浏览器url并更新全局状态。您已经巧妙地分配了一个url,该url与陷阱中的任何特殊情况相匹配。例如,“/login/ref/:toref”将是处理url”/login/ref的基本表达式/{specialaccess}”

    注意“:”

    正如他们所说,一行代码抵得上千言万语。因此,我做了一个小项目来充分展示如何实现
    react-router-dom
    的一些重要功能

    请在此处查找:

    在项目中,当您尝试通过浏览器模拟器访问时,在登录时通过身份验证后,您会被重定向到特殊访问页面。否则,如果您访问,则在登录后会被重定向到主页

    请记住,您必须将任何需要全局道具
    的组件包装为路由器
    ,如下所示:

    export default withRouter(component-name);
    
    这在每个组件中提供了
    This.props.location
    This.props.history
    This.props.match
    ,因为我们已经将应用程序的根组件放置在包中默认可用的
    HOC中

    使用
    this.props.match
    我们可以轻松地引用并重定向回前面在“:toref”中指定的url


    您可以阅读有关jwt的更多信息。请验证函数是否以异步回调方式使用

    这种样式更适合以这种方式使用的
    WrappedComponent
    componentDidMount
    生命周期方法。
    为其传递回调意味着,
    isValid
    的值可能永远不会足够早地更新,即使客户端JWT令牌是有效的,并且用户将始终被重定向

    我建议使用不带回调的同步变量(测试以比较呈现包装组件之前的时间)。更好的是,将
    jwt.verify
    回调样式转换为返回承诺的函数,这样就可以在
    await
    表达式中解析,因为
    getInitialProps
    是一个
    async
    函数

    if (req && req.headers) {
      const cookies = req.headers.cookie
      if (typeof cookies === 'string') {
        const cookiesJSON = jsHttpCookie.parse(cookies)
        initProps.token = cookiesJSON['auth-token']
        if (cookiesJSON['auth-token']) {
          try {
             const payload = jwt.verify(cookiesJSON['auth-token'], secret)
             if (payload) {
                isValid = true
             }
          } catch (err) {
             isValid = false
          }
        }
      }
    }
    
    现在,在重定向用户的
    \u onsubmit
    方法中,可以获得
    WrappedComponent.getInitialProps
    中设置的
    ref
    查询参数值,并使用该值重定向用户

    const ref = new URLSearchParams(location.search).get('ref');
    location.assign(`/${ref}`);
    

    将返回url作为查询参数或位置状态传递给登录页面。我在Next.js的文档页面上找到了一个使用查询参数推送路由的示例

    import Router from 'next/router'
    
    const handler = () => {
      Router.push({
        pathname: '/about',
        query: { name: 'Zeit' }
      })
    }
    
    export default () => (
      <div>
        Click <span onClick={handler}>here</span> to read more
      </div>
    )
    
    从“下一个/路由器”导入路由器
    常量处理程序=()=>{
    路由器推送({
    路径名:'/about',
    查询:{name:'Zeit'}
    })
    }
    导出默认值()=>(
    点击这里阅读更多
    )
    

    使用从HOC传入的返回url尝试Router.push,而不是Router.replace。希望这能有所帮助。

    中使用server props.js
    将路径替换为

    这将向url添加重定向参数https://example.com/?redirect=/about

    然后,您可以使用
    getInitialProps
    在任何页面上获取url参数:

    this.redirectUrl = (req && req.query['redirect']) ? decodeURIComponent(req.query['redirect']) : '/'
    
    最后

    window.location.assign(this.redirectUrl)
    

    希望有帮助,让我知道。

    听起来不错。我不太确定,但nextJS也有一个路由模块。如果是这样的话,是否可以以类似的方式使用该模块?可能类似于?是的,nextJS有它的路由模块,但它不像
    react router
    那样处理复杂的路由。从这里可以阅读
    react-router
    仍将用于nextJS。因此,如果您在前端执行动态路由,
    react-router
    仍然是您的最佳选择,至少据我所知。也许只需将初始url存储到本地/会话存储中,并在登录后检查它?在react中,传递数据的最优雅方式是通过道具。但“next/router”是这样做是没有办法通过道具传递数据的。而且因为你是替换而不是推送,所以它也不会保存在“历史记录”中。除了道具,还有多种传递数据的方法,例如“全局变量”、“本地存储”、“redux”等第三方存储。我认为使用“redux”或其他存储是更好的共享方式