Node.js HTTP Sunucusu ile Tek Bir Çerez Alma ve Ayarlama


159

Tek bir çerez ayarlamak ve nodejs sunucu örneğine yapılan her istek ile bu tek çerez okumak istiyorum. Üçüncü taraf bir lib çekmeye gerek kalmadan birkaç satır kod içinde yapılabilir mi?

var http = require('http');

http.createServer(function (request, response) {
  response.writeHead(200, {'Content-Type': 'text/plain'});
  response.end('Hello World\n');
}).listen(8124);

console.log('Server running at http://127.0.0.1:8124/');

Sadece yukarıdaki kodu doğrudan nodejs.org'dan almaya çalışın ve içine bir çerez çalışın.

Yanıtlar:


190

Çerezleri almak / ayarlamak için hızlı işlev erişimi yoktur, bu yüzden aşağıdaki hack ile geldim:

var http = require('http');

function parseCookies (request) {
    var list = {},
        rc = request.headers.cookie;

    rc && rc.split(';').forEach(function( cookie ) {
        var parts = cookie.split('=');
        list[parts.shift().trim()] = decodeURI(parts.join('='));
    });

    return list;
}


http.createServer(function (request, response) {

  // To Read a Cookie
  var cookies = parseCookies(request);

  // To Write a Cookie
  response.writeHead(200, {
    'Set-Cookie': 'mycookie=test',
    'Content-Type': 'text/plain'
  });
  response.end('Hello World\n');
}).listen(8124);

console.log('Server running at http://127.0.0.1:8124/');

Bu, tüm çerezleri çerez nesnesine depolar ve kafayı yazarken çerezleri ayarlamanız gerekir.


11
Çerezin değeri =, Facebook'un çerezlerinden birinde olduğu gibi eşit ( ) işareti içeriyorsa yukarıdaki kod yanlış çalışır fbm_1234123412341234=base_domain=.domain.com.
Göz

3
çerez değerlerinin URL kodlu / yüzde kodlanmış olması gerekmez mi? = doockie değerinde bu durumda geçersiz olur, değil mi?
les2

2
Bu durumda ;, ilk örneğine göre bölünür =. Sol anahtar, sağ değer.
iLoch

4
Ben açık yerine @iLoch I rotayı gitmeyi, @Eye aynı sorunu koştum parts[0]etmek parts.shift()ve parts[1]karşıparts.join('=')
aron.duby

3
Verilen kod ciddi hatalar vardı ve insanlar onu kopyalamak için görev yaptı. Son güncellememi görün
Dan

124

Ekspres kitaplığı kullanıyorsanız, birçok node.js geliştiricisinin yaptığı gibi, daha kolay bir yol vardır. Daha fazla bilgi için Express.js belgeler sayfasına bakın.

Yukarıdaki ayrıştırma örneği işe yarıyor ancak ekspres size bununla ilgilenmek için güzel bir işlev sunuyor:

app.use(express.cookieParser());

Bir çerez ayarlamak için:

res.cookie('cookiename', 'cookievalue', { maxAge: 900000, httpOnly: true });

Çerezi temizlemek için:

res.clearCookie('cookiename');

14
Çerez kütüphanesi aslında temeldeki kütüphane bağlantısıdır; çerez yardımcısı almak için tüm ifadeleri almanıza gerek yoktur.
Ajax

1
aslında çerez kütüphanesi
connect'in bir

10
cookie-parserartık ekspres ve / veya bağlanmanın bir parçası değildir, ancak ara katman yazılımı olarak kullanılabilir: github.com/expressjs/cookie-parser
Koen.

7
Bu örnekte bir çerez nasıl "elde edilir"? Bütünlüğü ve soruyu cevaplamak için.
hubatish

1
Sadece çerezleri kullanmak için ekspres kurmaya ihtiyaç duyduğu için aşağı oylama
Steven

34

RevNoah, Express'in çerez ayrıştırıcısını kullanma önerisiyle en iyi cevaba sahipti . Ancak, bu cevap şimdi 3 yaşında ve güncel değil.

Express'i kullanarak bir çerezi aşağıdaki gibi okuyabilirsiniz

var express = require('express');
var cookieParser = require('cookie-parser');
var app = express();
app.use(cookieParser());
app.get('/myapi', function(req, resp) {
   console.log(req.cookies['Your-Cookie-Name-Here']);
})

Ve package.jsonuygun nispeten en son sürümleri değiştirerek aşağıdakileri güncelleyin .

"dependencies": {
    "express": "4.12.3",
    "cookie-parser": "1.4.0"
  },

Çerezleri ayarlama ve ayrıştırma gibi daha fazla işlem burada ve burada açıklanmaktadır


8
Soru nasıl alınacağını ve ayarlanacağını sorar . Bunu ayarlamak için:res.cookie('cookieName', cookieValue, { maxAge: 900000, httpOnly: true });
Augie Gardner

Çerezleri oturum başına ayarlayabilir ve alabilirsiniz (anahtarları bilme ve işleme ihtiyacı olmadan)?
Matej J

12

@Corey Hart'ın cevabının bir geliştirmesi olarak şunu parseCookies()kullanarak yeniden yazdım :

İşte çalışma örneği:

let http = require('http');

function parseCookies(str) {
  let rx = /([^;=\s]*)=([^;]*)/g;
  let obj = { };
  for ( let m ; m = rx.exec(str) ; )
    obj[ m[1] ] = decodeURIComponent( m[2] );
  return obj;
}

function stringifyCookies(cookies) {
  return Object.entries( cookies )
    .map( ([k,v]) => k + '=' + encodeURIComponent(v) )
    .join( '; ');
}

http.createServer(function ( request, response ) {
  let cookies = parseCookies( request.headers.cookie );
  console.log( 'Input cookies: ', cookies );
  cookies.search = 'google';
  if ( cookies.counter )
    cookies.counter++;
  else
    cookies.counter = 1;
  console.log( 'Output cookies: ', cookies );
  response.writeHead( 200, {
    'Set-Cookie': stringifyCookies(cookies),
    'Content-Type': 'text/plain'
  } );
  response.end('Hello World\n');
} ).listen(1234);

OP'nin http modülünü kullandığını da unutmayın. OP restify kullanıyorsa, restify çerezlerinden yararlanabilir :

var CookieParser = require('restify-cookies');
var Restify = require('restify');
var server = Restify.createServer();
server.use(CookieParser.parse);
server.get('/', function(req, res, next){
  var cookies = req.cookies; // Gets read-only cookies from the request
  res.setCookie('my-new-cookie', 'Hi There'); // Adds a new cookie to the response
  res.send(JSON.stringify(cookies));
});
server.listen(8080);

1
3,5 yıl sonra gelecekteki izleyiciler için bazı önerilerde bulunuldu. Kullanın let/constve bu şekilde bir dizi oluşturmak yerine stringifyCookiesbir tane olabilir map.
Ascherer

10

Kapsamlı özelliklere sahip "çerezler" npm modülünü kullanabilirsiniz.

Belgeler ve örnekler:
https://github.com/jed/cookies


1
Bu modül http sunucularında kullanılmak üzere tasarlanmış gibi görünüyor. Http istemcilerinde çerezleri işlemek için bir çerez çerezi var mı? Temelde http istemcisi lib anlatmak için aant: Herhangi bir Set-Cookie üstbilgileri alırsanız, otomatik olarak hatırlamak ve daha sonra uygun olarak (etki alanı eşleştiğinde) sonraki giden istekleri iletmek.
Cheeso

Bu, seçtiğiniz http istemci kitaplığınızın bir özelliği olacaktır. Superagent'ı iyi bir örnek olarak önerebilirim .
zah

Birkaç saat sonra bu lib'in hızlı bir şekilde çalışmasını sağlamaya çalıştım ... bunun yerine connect kullanın.
enko

7

Bir çerez ayırıcısının çerez değerlerinde '=' bulunan çerezlerle çalışmasını sağlamak için:

var get_cookies = function(request) {
  var cookies = {};
  request.headers && request.headers.cookie.split(';').forEach(function(cookie) {
    var parts = cookie.match(/(.*?)=(.*)$/)
    cookies[ parts[1].trim() ] = (parts[2] || '').trim();
  });
  return cookies;
};

bireysel bir çerez almak için:

get_cookies(request)['my_cookie']


2

Düğümdeki çerezleri yönetmek için düzgün bir kopyala ve yapıştır yama. Bunu güzellik için CoffeeScript'te yapacağım.

http = require 'http'

http.IncomingMessage::getCookie = (name) ->
  cookies = {}
  this.headers.cookie && this.headers.cookie.split(';').forEach (cookie) ->
    parts = cookie.split '='
    cookies[parts[0].trim()] = (parts[1] || '').trim()
    return

  return cookies[name] || null

http.IncomingMessage::getCookies = ->
  cookies = {}
  this.headers.cookie && this.headers.cookie.split(';').forEach (cookie) ->
    parts = cookie.split '='
    cookies[parts[0].trim()] = (parts[1] || '').trim()
    return

  return cookies

http.OutgoingMessage::setCookie = (name, value, exdays, domain, path) ->
  cookies = this.getHeader 'Set-Cookie'
  if typeof cookies isnt 'object'
    cookies = []

  exdate = new Date()
  exdate.setDate(exdate.getDate() + exdays);
  cookieText = name+'='+value+';expires='+exdate.toUTCString()+';'
  if domain
    cookieText += 'domain='+domain+';'
  if path
    cookieText += 'path='+path+';'

  cookies.push cookieText
  this.setHeader 'Set-Cookie', cookies
  return

Artık çerezleri beklediğiniz gibi işleyebileceksiniz:

server = http.createServer (request, response) ->
  #get individually
  cookieValue = request.getCookie 'testCookie'
  console.log 'testCookie\'s value is '+cookieValue

  #get altogether
  allCookies = request.getCookies()
  console.log allCookies

  #set
  response.setCookie 'newCookie', 'cookieValue', 30

  response.end 'I luvs da cookies';
  return

server.listen 8080

3
Bu kodu coffeescript.org'daki TRY COFFESCRIPT sekmesine kopyalamanız yeterlidir . Cevabınız bana yardımcı oldu ve javascript biliyorsanız kahve okumak o kadar zor değil.
Mattijs

1

Burada cevapların görmezden geldiği sorunun bu kısmını tekrarlayayım:

Üçüncü taraf bir lib çekmeye gerek kalmadan birkaç satır kod içinde yapılabilir mi?


Çerezleri Okuma

Çerezler Cookiebaşlıklı isteklerden okunur . Sadece bir nameve içerirler value. Yolların çalışması nedeniyle, aynı adda birden çok çerez gönderilebilir. NodeJS'de, tüm Çerezler Cookiebaşlıkta gönderildikleri gibi tek bir dizede bulunur . Onları ayırdın ;. Bir çereziniz olduğunda, (varsa) eşitlerin solundaki nameher şey, ve sonraki her şey value. Bazı tarayıcılar eşit işareti olmayan bir çerezi kabul eder ve adının boş olduğunu varsayar. Beyaz alanlar çerezin bir parçası olarak sayılmaz. Değerler ayrıca çift tırnak işareti ( ") ile sarılabilir . Değerler de içerebilir =. Örneğin, formula=5+3=8geçerli bir çerezdir.

/**
 * @param {string} [cookieString='']
 * @return {[string,string][]} String Tuple
 */
function getEntriesFromCookie(cookieString = '') {
  return cookieString.split(';').map((pair) => {
    const indexOfEquals = pair.indexOf('=');
    let name;
    let value;
    if (indexOfEquals === -1) {
      name = '';
      value = pair.trim();
    } else {
      name = pair.substr(0, indexOfEquals).trim();
      value = pair.substr(indexOfEquals + 1).trim();
    }
    const firstQuote = value.indexOf('"');
    const lastQuote = value.lastIndexOf('"');
    if (firstQuote !== -1 && lastQuote !== -1) {
      value = value.substring(firstQuote + 1, lastQuote);
    }
    return [name, value];
  });
}

const cookieEntries = getEntriesFromCookie(request.headers.Cookie); 
const object = Object.fromEntries(cookieEntries.slice().reverse());

Yinelenen adlar beklemiyorsanız, işleri kolaylaştıran bir nesneye dönüştürebilirsiniz. Sonra object.myCookieNamedeğeri almak için beğenebilirsiniz . Yinelenenleri bekliyorsanız, yineleme yapmak istersiniz cookieEntries. Tarayıcılar çerezleri azalan önceliğe göre besler, böylece tersine çevirme en yüksek öncelikli çerezin nesnede görünmesini sağlar. (Dizinin .slice()mutasyonunu önlemek içindir.)


Ayar Çerezleri

"Yazma" çerezleri Set-Cookieyanıtınızdaki başlık kullanılarak yapılır . response.headers['Set-Cookie']Nesne aslında bir dizidir, bu nedenle buna bastırıyor olacak. Bir dizeyi kabul eder ancak sadece nameve değerlerinden daha fazla değere sahiptir value. En zor kısmı dizeyi yazmak, ancak bu bir satırda yapılabilir.

/**
 * @param {Object} options
 * @param {string} [options.name='']
 * @param {string} [options.value='']
 * @param {Date} [options.expires]
 * @param {number} [options.maxAge]
 * @param {string} [options.domain]
 * @param {string} [options.path]
 * @param {boolean} [options.secure]
 * @param {boolean} [options.httpOnly]
 * @param {'Strict'|'Lax'|'None'} [options.sameSite]
 * @return {string}
 */
function createSetCookie(options) {
  return (`${options.name || ''}=${options.value || ''}`)
    + (options.expires != null ? `; Expires=${options.expires.toUTCString()}` : '')
    + (options.maxAge != null ? `; Max-Age=${options.maxAge}` : '')
    + (options.domain != null ? `; Domain=${options.domain}` : '')
    + (options.path != null ? `; Path=${options.path}` : '')
    + (options.secure ? '; Secure' : '')
    + (options.httpOnly ? '; HttpOnly' : '')
    + (options.sameSite != null ? `; SameSite=${options.sameSite}` : '');
}

const newCookie = createSetCookie({
  name: 'cookieName',
  value: 'cookieValue',
  path:'/',
});
response.headers['Set-Cookie'].push(newCookie);

Birden çok çerez ayarlayabileceğinizi unutmayın, çünkü Set-Cookieisteğinizde aslında birden çok başlık ayarlayabilirsiniz . Bu yüzden bir dizi.


Harici kitaplıklar hakkında not:

, Veya kullanmaya karar verirseniz express, standart olmayan varsayılan değerleri olduğunu unutmayın. Ayrıştırılan çerezler her zaman URI Kod Çözücüdür (yüzde kod çözme). Bu, aşağıdaki karakterlerden herhangi birine sahip bir ad veya değer kullanırsanız, bu kitaplıklarla farklı şekilde işlenecekleri anlamına gelir . Çerezleri ayarlıyorsanız, bunlar ile kodlanır . Eğer bir çerez okuyorsanız bunları deşifre etmelisiniz.cookie-parsercookie!#$%&'()*+/:<=>?@[]^`{|}%{HEX}

Örneğin, email=name@domain.comgeçerli bir çerez olsa da, bu kütüphaneler onu olarak kodlar email=name%40domain.com. Eğer %çerezi içinde kullanıyorsanız kod çözme sorunları gösterebilir . Karışık olacak. Örneğin, olan çereziniz: secretagentlevel=50%007and50%006olursecretagentlevel=507and506 . Bu bir uç durum, ama kütüphaneleri değiştirirken dikkat edilmesi gereken bir şey.

Ayrıca, bu kütüphanelerde, çerezler varsayılan olarak ayarlanır, path=/yani her url isteğinde ana bilgisayara gönderilir.

Bu değerleri kendiniz kodlamak veya kodunu çözmek isterseniz , sırasıyla encodeURIComponentveya kullanabilirsiniz decodeURIComponent.


Referanslar:


Ek bilgi:


0

İlk olarak bir çerez oluşturmak gerekir (Ben örnek olarak çerez içine jeton sarılmış) ve sonra yanıt olarak ayarlayın. Çerez aşağıdaki şekilde kullanmak için cookieParser

app.use(cookieParser());

Tarayıcı, 'Kaynak' sekmesine kaydedecek ve daha sonra ilk URL'yi temel alarak her istek için kullanılacak

var token = student.generateToken('authentication');
        res.cookie('token', token, {
            expires: new Date(Date.now() + 9999999),
            httpOnly: false
        }).status(200).send();

Sunucu tarafındaki bir istekten çerez almak da kolaydır.

var token = req.cookies.token; // Retrieving Token stored in cookies

0

cookieİçinde ne olduğunu umursamıyorsanız ve sadece kullanmak istiyorsanız, request(popüler bir düğüm modülü) kullanarak bu temiz yaklaşımı deneyin :

var request = require('request');
var j = request.jar();
var request = request.defaults({jar:j});
request('http://www.google.com', function () {
  request('http://images.google.com', function (error, response, body){
     // this request will will have the cookie which first request received
     // do stuff
  });
});

Üzgünüm, ama bu kod benim için hiçbir anlam ifade etmiyor. Mı jar()çerez geçerli listesini almak için bazı şirin yöntemi adı? 2 talep çağrısının anlamı nedir? Bu çoğunlukla bir reklam, cevap değil.
user1944491

0
var cookie = 'your_cookie';
var cookie_value;
var i = request.headers.indexOf(cookie+'=');
if (i != -1) {
  var eq = i+cookie.length+1;
  var end = request.headers.indexOf(';', eq);
  cookie_value = request.headers.substring(eq, end == -1 ? undefined : end);
}

0

Bazı ES5 / 6 Büyücüyü ve RegEx Magic'i Kullanma

Çerezleri okumak ve onları bir anahtar nesnesine dönüştürmek için bir seçenek var, İstemci tarafı için değer çiftleri, sunucu tarafı da kullanabilir.

Not : Değerde bir varsa, =endişelenmeyin. =Anahtarda bir varsa , cennette sorun.

Daha Fazla Not : Bazıları okunabilirliği savunabilir, bu yüzden istediğiniz gibi bozun.

Notları Seviyorum : Bir hata işleyici (catch'i deneyin) eklemek zarar vermez.

const iLikeCookies = () => {
    return Object.fromEntries(document.cookie.split('; ').map(v => v.split(/=(.+)/))); 
}

const main = () => {
    // Add Test Cookies
    document.cookie = `name=Cookie Monster;expires=false;domain=localhost`
    document.cookie = `likesCookies=yes=withARandomEquals;expires=false;domain=localhost`;

    // Show the Objects
    console.log(document.cookie)
    console.log('The Object:', iLikeCookies())

    // Get a value from key
    console.log(`Username: ${iLikeCookies().name}`)
    console.log(`Enjoys Cookies: ${iLikeCookies().likesCookies}`)
}

resim açıklamasını buraya girin

Ne oluyor?

iLikeCookies()çerezleri bölecek ;( sonraki boşluk; ):

["name=Cookie Monster", "likesCookies=yes=withARandomEquals"]

Daha sonra bu diziyi eşleriz ve regex yakalama parenleri= kullanmanın ilk oluşumuna göre ayrılırız :

[["name", "Cookie Monster"], ["likesCookies", "yes=withARandomEquals"]]

Sonra arkadaşımızı `Object.fromEntries 'i kullanarak bunu anahtar, val çiftleri nesnesi haline getirin.

Nooice.


0

Sadece geçen bu basit bir fonksiyon yazdım req.headers.cookieve çerez adını

const getCookieByName =(cookies,name)=>{
    const arrOfCookies = cookies.split(' ')
    let yourCookie = null

    arrOfCookies.forEach(element => {
        if(element.includes(name)){
            yourCookie = element.replace(name+'=','')
        }
    });
    return yourCookie
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.