【问题标题】:How to pass cookie value to all routes with express.js?如何使用 express.js 将 cookie 值传递给所有路由?
【发布时间】:2019-05-31 17:35:25
【问题描述】:

我正在试验 Next.js,它使用 Express.js 作为服务器。我想通过检查用户的身份验证cookie是否存在来对服务器上的用户进行身份验证(登录时在客户端上设置了cookie)。

这是我的做法(我正在自定义下一个默认 server.js 文件):

const express = require( 'express' )
const next = require( 'next' )

const cookiesMiddleware = require( 'universal-cookie-express' )
const dev = process.env.NODE_ENV !== 'production'
const app = next( { dev } )
const handle = app.getRequestHandler()

app.prepare().then( async () => {

    const server = express()

    server.use( cookiesMiddleware() )

    server.get( '/news', ( req, res ) => {
        const actualPage = '/news'
        const userID = req.universalCookies.get( 'userID' )
        const queryParams = { userID: userID }
        app.render( req, res, actualPage, queryParams )
    })  

    server.get( '*', ( req, res ) => {
        return handle( req, res )
    }) 

    server.listen( 3000, ( err ) => {
        if( err ) throw err
        console.log( '> Ready on http://localhost:3000' )
    })

})

所以基本上我使用universal-cookie-express 包作为中间件从请求中读取userID cookie,并将其作为参数传递给/news 路由,它有自己特殊的server.get,因为它必须按照 Next.js 的说明使用自己的页面呈现。

然后在新闻页面,我得到getInitialProps中的cookie值:

static async getInitialProps( { query } ) {
    const { userID } = query
    return { userID }
}

render() {
    return <p>The user ID is { this.props.userID }</p>
}

这是非常好的。

顺便说一句,上面的代码有效。问题是我有几个不同的路线,不想在每个server.get 函数中读取cookie。所以我的问题是,如何读取userID cookie 并将其传递给所有路由,以及如何在每个页面中访问它?

【问题讨论】:

    标签: javascript express cookies next.js


    【解决方案1】:

    我发现自己是一个非常巧妙的解决方案。在设置路线之前,我刚刚添加了以下内容:

    server.use( ( req, res, next ) => {
        req.userID = req.universalCookies.get( 'userID' )
        req.userToken = req.universalCookies.get( 'userToken' )
        next()
    })   
    

    通过将 cookie 附加到 req 对象,这使得 cookie 可用于每个路由。所以在服务器上你可以按如下方式访问它:

    server.get( '/news', ( req, res ) => {
        console.log( 'User ID is', req.userID )
    })  
    

    在客户端,如果你和我一样使用 Next,你可以在 getInitialProps 访问它:

    static async getInitialProps( { req } ) {
        console.log( 'User ID is', req.userID ) 
    }
    

    【讨论】:

      【解决方案2】:

      有几种方法可以做到这一点:

      1. 使用反应状态管理(redux/fluxible)

        Read more about redux

        Read more about fluxible

      2. 使用react-cookies 依赖

      import { Component } from 'react'
      import cookie from 'react-cookies'
      
      class MyApp extends Component {
        constructor () {
          super()
          this.onLogin = this.onLogin.bind(this)
          this.onLogout = this.onLogout.bind(this)
        }
      
        componentWillMount() {
          // Get the userID value from react-cookie
          this.state =  { userId: cookie.load('userId') }
        }
      
        onLogin(userId) {
          this.setState({ userId })
          // Store the cookie in react-cookie
          cookie.save('userId', userId, { path: '/' })
        }
      
        onLogout() {
          // Destroy the cookie from react-cookie
          cookie.remove('userId', { path: '/' })
        }
      
        render() {
          const { userId } = this.state
          return (
            <div />
          );
        }
      }
      1. 使用窗口 sessionStorage

        Sessionstorage 为每个给定的源维护一个单独的存储区域,该区域在页面会话期间可用(只要浏览器处于打开状态,包括页面重新加载和恢复)。一旦浏览器关闭并重新打开,会话就会自动销毁。

        // Store the cookie
        sessionStorage.setItem("userId", userId);
        // Get the value of cookie
        sessionStorage.getItem("userId");

      【讨论】:

      • 谢谢,但我一直在寻找可以在服务器文件中使用的东西,因为我觉得这只是一种更清洁的方法。我从来没有真正使用过 Express,但我读过 express.all() 之类的方法,我认为它可以满足我的需要,但我似乎无法自己弄清楚......
      猜你喜欢
      • 2020-05-10
      • 1970-01-01
      • 2022-06-25
      • 2013-05-23
      • 2015-08-16
      • 2017-02-22
      • 2015-04-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多