JS:如何通过重定向功能将网址传递到登录功能

时间:2018-11-17 21:21:36

标签: javascript node.js reactjs redirect next.js

在我的React / nextJS应用程序中,我正在检查getInitialProps静态函数中的有效令牌。 我将其用作HOC-但这在这种情况下无关紧要。

如果令牌无效(或丢失),则用户将被重定向到登录页面。如下所示,这是通过redirect函数完成的。到目前为止,一切都很好。

如何将用户重定向到的页面URL传递到登录组件?

如果用户未登录并正在调用类似 http://my-server.com/any-page 之类的东西,他将被重定向到索引页面( http://my-server.com ):将有一个登录表格。如果登录成功,我想将他重定向回第一个被调用的页面: http://my-server.com/any-page

  1. 以未登录用户的身份呼叫受限页面
  2. 重定向到索引登录页面
  3. 登录后重定向到1.页面。

我不知道如何将此信息传递给登录功能...

with-server-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} />
    }
  }

redirect.js

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)
  }
}

pages / index.js

在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
      })
    }
  })
}

4 个答案:

答案 0 :(得分:2)

在您的with-server-props.js中,将路径替换为URL object

redirect(context, {
    pathname: '/',
    query: { redirect: req.url } // req.url should give you the current url on server side
  })

这会将重定向参数添加到网址 https://example.com/?redirect=/about

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

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

最终

window.location.assign(this.redirectUrl)

希望有帮助,让我知道。

答案 1 :(得分:0)

您需要的是react-router,或更具体地说是react-router-dom软件包。如果您了解它的工作方式,那就轻而易举。

对于您的情况,您使用redirect()而不是在未通过身份验证时调用<Redirect to={url} />。这会自动执行浏览器URL替换并更新全局状态。您已经巧妙地分配了一个与任何特殊情况匹配的URL来进行陷阱。例如。 “ / login / ref /:toref”将是处理URL“ / login / ref / {specialaccess}”的基本表达式。

注意“:”。它是参数匹配器,在登录组件中检索URL是必需的。

正如他们所说,一行代码值得一千个单词。因此,我做了一个小项目,以充分展示如何实现react-router-dom的某些重要功能。

在这里找到:https://codesandbox.io/s/y0znxpk30z

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

请记住,您必须像这样包装所有需要全局道具withRouter的组件:

export default withRouter(component-name);

这在每个组件中提供了this.props.locationthis.props.historythis.props.match,因为我们已经将应用程序的根组件放置在<BrowserRouter><BrowserRouter/> HOC中,默认情况下可从该软件包中获得。

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

您可以了解有关react-router here

的更多信息

答案 2 :(得分:0)

jwt.verify函数以异步回调方式使用。

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

我建议使用不带回调的同步变量(测试以比较呈现封装的组件之前有多少时间)。甚至更好的是,将isValid回调样式转换为返回诺言的函数,以便在jwt.verifyawait函数的情况下,可以在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 } } } } 方法中重定向用户,您可以获得在_onsubmit中设置的ref查询参数值,并使用该值来重定向用户。

WrappedComponent.getInitialProps

答案 3 :(得分:0)

将返回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>
)

而不是Router.replace,请尝试将Router.push与从HOC传入的返回URL一起使用。希望这会有所帮助。