简体   繁体   English

如何使用 express.js 将 cookie 值传递给所有路由?

[英]How to pass cookie value to all routes with express.js?

I'm experimenting with Next.js which uses Express.js as a server.我正在试验 Next.js,它使用 Express.js 作为服务器。 I'd like to authenticate the user on the server by checking if the user's authentication cookie is present (the cookie is set on the client at the moment of login).我想通过检查用户的身份验证 cookie 是否存在来对服务器上的用户进行身份验证(cookie 是在登录时在客户端上设置的)。

Here's how I'm doing it (I'm customiziong the Next default server.js file):这是我的做法(我正在自定义下一个默认 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' )
    })

})

So basically I'm using the universal-cookie-express package as a middleware to read the userID cookie from the request, and passing it as a parameter to the /news route, which has its own special server.get because it must be rendered with its own page, as per Next.js instructions.所以基本上我使用universal-cookie-express包作为中间件从请求中读取userID cookie,并将其作为参数传递给/news路由,它有自己的特殊server.get因为它必须被渲染根据 Next.js 说明,有自己的页面。

Then in the news page, I get the cookie value in getInitialProps :然后在新闻页面中,我在getInitialProps获取 cookie 值:

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

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

which is very nice.这是非常好的。

The above code works, by the way.顺便说一下,上面的代码有效。 The problem is I have several different routes and wouldn't want to read the cookie in each server.get function.问题是我有几个不同的路由,不想在每个server.get函数中读取 cookie。 So my question is, how do I read the userID cookie and pass it to all routes, and how do I access it in each page?所以我的问题是,如何读取userID cookie 并将其传递给所有路由,以及如何在每个页面中访问它?

I found myself a very neat solution.我发现自己有一个非常巧妙的解决方案。 I've just added the following before setting up my routes:在设置路线之前,我刚刚添加了以下内容:

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

This makes the cookies available for each routes by attaching it to the req object.通过将 cookie 附加到req对象,这使得每个路由都可以使用 cookie。 So on the server you would access it as follows:因此,在服务器上,您可以按如下方式访问它:

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

and on the client, if you're using Next like me, you can access it in getInitialProps :在客户端,如果你像我一样使用 Next,你可以在getInitialProps访问它:

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

There are a few ways to accomplish that:有几种方法可以实现:

  1. Using react state management (redux/fluxible) .使用反应状态管理(redux/fluxible)

    Read more about redux阅读更多关于 redux

    Read more about fluxible阅读更多关于fluxible

  2. Using react-cookies dependency .使用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. Using window sessionStorage .使用窗口 sessionStorage

    Sessionstorage maintains a separate storage area for each given origin that's available for the duration of the page session (as long as the browser is open, including page reloads and restores). Sessionstorage 为每个给定的源维护一个单独的存储区域,在页面会话期间可用(只要浏览器打开,包括页面重新加载和恢复)。 Once the browser is closed and reopened, the session automatically destroyed.一旦浏览器关闭并重新打开,会话就会自动销毁。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM