Wie setze ich ein Cookie in Knoten js mit dem Express-Framework?


161

In meiner Anwendung muss ich ein Cookie mithilfe des Express-Frameworks setzen. Ich habe den folgenden Code ausprobiert, aber das Cookie wird nicht gesetzt.

Kann mir jemand dabei helfen?

var express = require('express'), http = require('http');
var app = express();
app.configure(function(){
      app.use(express.cookieParser());
      app.use(express.static(__dirname + '/public'));

      app.use(function (req, res) {
           var randomNumber=Math.random().toString();
           randomNumber=randomNumber.substring(2,randomNumber.length);
           res.cookie('cokkieName',randomNumber, { maxAge: 900000, httpOnly: true })

           console.log('cookie have created successfully');
      });

});

var server = http.createServer(app);
var io = require('socket.io').listen(server);
server.listen(5555);

Wie überprüfen Sie, ob das Cookie nicht gesetzt ist? Haben Sie die Antwortheader überprüft, die der Browser erhält?
NilsH

@NilsH Ich habe Log-Anweisung hinzugefügt. Wenn es gesetzt ist, bedeutet es, dass es als "Cookie wurde erfolgreich erstellt" angezeigt wird.
Sachin

1
OK, dann wird entweder Ihre Middleware nicht aufgerufen oder einige der vorherigen Anweisungen geben eine Ausnahme.
NilsH

wenn ich 'app.use (express.static (__ dirname +' / public ')) entfernt habe;' Diese Linie bedeutet , es ist das Cookie gesetzt
sachin

Antworten:


216

Die Reihenfolge, in der Sie Middleware in Express verwenden: Die zuvor deklarierte Middleware wird zuerst aufgerufen, und wenn sie eine Anforderung verarbeiten kann, wird eine später deklarierte Middleware nicht aufgerufen.

Wenn express.staticdie Anfrage bearbeitet wird, müssen Sie Ihre Middleware nach oben verschieben:

// need cookieParser middleware before we can do anything with cookies
app.use(express.cookieParser());

// set a cookie
app.use(function (req, res, next) {
  // check if client sent cookie
  var cookie = req.cookies.cookieName;
  if (cookie === undefined) {
    // no: set a new cookie
    var randomNumber=Math.random().toString();
    randomNumber=randomNumber.substring(2,randomNumber.length);
    res.cookie('cookieName',randomNumber, { maxAge: 900000, httpOnly: true });
    console.log('cookie created successfully');
  } else {
    // yes, cookie was already present 
    console.log('cookie exists', cookie);
  } 
  next(); // <-- important!
});

// let static middleware do its job
app.use(express.static(__dirname + '/public'));

Außerdem muss die Middleware entweder eine Anforderung beenden (indem sie eine Antwort zurücksendet) oder die Anforderung an die nächste Middleware weiterleiten. In diesem Fall habe ich Letzteres getan, indem ich aufgerufen habe, next()wenn das Cookie gesetzt wurde.

Aktualisieren

Ab sofort ist der Cookie-Parser ein separates npm-Paket, also anstatt zu verwenden

app.use(express.cookieParser());

Sie müssen es separat installieren npm i cookie-parserund dann verwenden als:

const cookieParser = require('cookie-parser');
app.use(cookieParser());

Außerdem habe ich noch eine Frage, wie ich überprüfen kann, ob der Cokkie vorhanden ist oder nicht, bevor
ich

Ich habe meine Antwort bearbeitet, um Ihnen zu zeigen, wie Sie überprüfen können, ob das Cookie bereits gesetzt ist.
Robertklep

1
Sie haben wahrscheinlich einige JS- und / oder CSS-Dateien auf Ihrer Seite. Diese werden von behandelt express.static, die sie nach Ihrer Middleware behandeln. Für jede JS- oder CSS-Datei wird der Code aufgerufen.
Robertklep

1
Der Cookie wird nicht achtmal gesetzt, sondern es wird angegeben, dass der Cookie bereits vorhanden ist. Welches ist zu erwarten.
Robertklep

13
Beachten Sie, dass der Cookie-Parser jetzt separat installiert werden sollte. Siehe npmjs.com/package/cookie-parser
Joshua

117

Cookie setzen?

res.cookie('cookieName', 'cookieValue')

Cookie lesen?

req.cookies

Demo

const express('express')
    , cookieParser = require('cookie-parser'); // in order to read cookie sent from client

app.get('/', (req,res)=>{

    // read cookies
    console.log(req.cookies) 

    let options = {
        maxAge: 1000 * 60 * 15, // would expire after 15 minutes
        httpOnly: true, // The cookie only accessible by the web server
        signed: true // Indicates if the cookie should be signed
    }

    // Set cookie
    res.cookie('cookieName', 'cookieValue', options) // options is optional
    res.send('')

})

Hallo, könntest du sagen, was signiert ist: wahr?
11.

Wenn Sie empfohlen haben, Cookie als Vorzeichen zu setzen, ist es wichtig zu beachten, dass req.cookie leer zurückgegeben wird. Sie können signierte Cookies nur von req.signedCookies
Someone Special

38

Ich habe Ihre Frage nicht genau beantwortet, aber ich bin auf Ihre Frage gestoßen, als ich nach einer Antwort auf ein Problem gesucht habe, das ich hatte. Vielleicht hilft es jemand anderem.

Mein Problem war, dass Cookies in der Serverantwort gesetzt wurden, aber nicht vom Browser gespeichert wurden.

Die Serverantwort kam mit gesetzten Cookies zurück:

Set-Cookie:my_cookie=HelloWorld; Path=/; Expires=Wed, 15 Mar 2017 15:59:59 GMT 

So habe ich es gelöst.

Ich habe fetchim clientseitigen Code verwendet. Wenn Sie credentials: 'include' in den fetchOptionen nichts angeben , werden Cookies weder an den Server gesendet noch vom Browser gespeichert, obwohl die Serverantwort Cookies setzt.

Beispiel:

var headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');

return fetch('/your/server_endpoint', {
    method: 'POST',
    mode: 'same-origin',
    redirect: 'follow',
    credentials: 'include', // Don't forget to specify this if you need cookies
    headers: headers,
    body: JSON.stringify({
        first_name: 'John',
        last_name: 'Doe'
    })
})

Ich hoffe das hilft jemandem.


Ich habe meine Post-Anfrage im Browser überprüft, aber dieses Feld passt nicht zur Post-Anfrage.
Sunil Garg

Bei der Verwendung von XHR oder JQuery, verwenden Sie 'withCredentials: true' statt
unplugged

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.