首页 > 解决方案 > JS: How to pass url through redirect function to login function

问题描述

In my React/nextJS application I'm checking for a valid token in the getInitialProps static function. I'm using this as a HOC - but this should not matter in this case.

If the the token is invalid (or missing) the user gets redirected to the login page. This is done by the redirect function as shown below. So far, so good.

How can I pass the url of the page from which the user gets redirected to the login component?

If the user is not logged in and is calling something like http://my-server.com/any-page, he gets redirected to the index page (http://my-server.com): There will be a login form. If the login is successful, I would like to redirect him back to the first called page: http://my-server.com/any-page

  1. Call a restricted page as not logged in user
  2. Redirect to index login page
  3. After login redirect back to the page of 1.

I don't have a clue how to pass this information to the login function...

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

On index.js there is the submit function to login the user. There the user should be redirected to the initial page:

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

标签: javascriptnode.jsreactjsredirectnext.js

解决方案


with-server-props.jsURL 对象替换路径

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

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

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

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

最后

window.location.assign(this.redirectUrl)

希望它有帮助,让我知道。


推荐阅读