programing

Node.js HTTP 서버를 사용하여 단일 쿠키 가져오기 및 설정

lastcode 2023. 8. 5. 10:16
반응형

Node.js HTTP 서버를 사용하여 단일 쿠키 가져오기 및 설정

단일 쿠키를 설정하고 nodejs 서버 인스턴스에 요청할 때마다 해당 단일 쿠키를 읽을 수 있기를 원합니다.제3자 lib를 끌어들일 필요 없이 몇 줄의 코드로 수행할 수 있습니까?

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/');

nodejs.org 에서 직접 위의 코드를 가져와서 쿠키를 작업하려고 합니다.

쿠키를 가져오거나 설정할 수 있는 빠른 기능이 없기 때문에 다음과 같은 해킹을 생각해냈습니다.

const http = require('http');

function parseCookies (request) {
    const list = {};
    const cookieHeader = request.headers?.cookie;
    if (!cookieHeader) return list;

    cookieHeader.split(`;`).forEach(function(cookie) {
        let [ name, ...rest] = cookie.split(`=`);
        name = name?.trim();
        if (!name) return;
        const value = rest.join(`=`).trim();
        if (!value) return;
        list[name] = decodeURIComponent(value);
    });

    return list;
}

const server = http.createServer(function (request, response) {
    // To Read a Cookie
    const 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);

const {address, port} = server.address();
console.log(`Server running at http://${address}:${port}`);

이렇게 하면 모든 쿠키가 쿠키 개체에 저장되며, 머리글을 쓸 때 쿠키를 설정해야 합니다.

많은 node.js 개발자가 사용하는 것처럼 Express 라이브러리를 사용하는 경우 더 쉬운 방법이 있습니다.자세한 내용은 Express.js 설명서 페이지를 참조하십시오.

위의 구문 분석 예제는 작동하지만 express를 사용하면 다음과 같은 문제를 해결할 수 있습니다.

app.use(express.cookieParser());

쿠키 설정하기

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

쿠키 지우기:

res.clearCookie('cookiename');

RevNoah는 Express의 쿠키 파서를 사용하자는 제안으로 가장 좋은 답변을 얻었습니다.하지만, 그 대답은 이제 3년이 되었고 시대에 뒤떨어졌습니다.

Express를 사용하면 다음과 같이 쿠키를 읽을 수 있습니다.

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']);
})

당신의 합다니업을 하세요.package.json다음을 사용하여 적절한 비교적 최신 버전으로 대체합니다.

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

쿠키 설정 및 구문 분석과 같은 더 많은 작업이 여기와 여기에 설명되어 있습니다.

@Corey Hart의 답변을 개선하기 위해, 저는 다음을 다시 썼습니다.parseCookies()매개 변수:

다음은 작업 예제입니다.

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가 http 모듈을 사용한다는 점도 참고합니다.OP가 restify를 사용하고 있다면, 그는 restify-cookies를 사용할 수 있습니다.

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);

여기서 답변이 무시하는 질문의 이 부분을 반복하겠습니다.

제3자 lib를 끌어들일 필요 없이 몇 줄의 코드로 수행할 수 있습니까?


쿠키 읽기

쿠키는 의 요청에서 읽습니다.Cookie표제의다음만 포함됩니다.name그리고.value경로가 작동하기 때문에 동일한 이름의 쿠키를 여러 개 보낼 수 있습니다.에서 될 때 됩니다.JS에서 모든 쿠키는 하나의 문자열로 전송됩니다.Cookie표제의당신은 그것들을 나누었습니다.;일단 쿠키를 가지고 있으면, 동등한 것들의 왼쪽에 있는 모든 것들(있는 경우)은name 그 의 모든 은 그고그이모것은든의후리▁the입니다.value일부 브라우저는 동일한 기호가 없는 쿠키를 허용하고 이름을 공백으로 가정합니다.공백은 쿠키의 일부로 계산되지 않습니다.큰따옴표로 .") 값은 다음을 포함할 수도 있습니다.=를 들어, .를들면예,formula=5+3=8유효한 쿠키입니다.

/**
 * @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());

중복된 이름을 사용하지 않을 경우 개체로 변환하여 작업을 더 쉽게 수행할 수 있습니다.그러면 다음과 같이 액세스할 수 있습니다.object.myCookieName값을 얻기 위해.된다면, ▁through다를 통해 .cookieEntries브라우저는 쿠키를 내림차순 우선 순위로 공급하므로 반대로 하면 개체에 가장 높은 우선 순위의 쿠키가 나타납니다.(그.slice()배열의 돌연변이를 방지하기 위한 것입니다.)


설정 쿠키

"쓰기" 쿠키는 다음을 사용하여 수행됩니다.Set-Cookie당신의 응답의 헤더.response.headers['Set-Cookie']객체는 실제로 배열이므로, 당신은 그것을 밀고 나갈 것입니다.문자열을 사용할 수 있지만 값이 더 많습니다.name그리고.value가장 어려운 부분은 현을 쓰는 것이지만, 이것은 한 줄로 할 수 있습니다.

/**
 * @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);

여러 할 수 개의 쿠키를 설정할 수 .Set-Cookie헤더를 입력합니다.그래서 이게 배열인 거예요.


외부 라이브러리에 대한 참고:

을 .express,cookie-parser또는cookie비표준 기본값이 있습니다.구문 분석된 쿠키는 항상 URI 디코딩(백분율 디코딩)됩니다.즉, 다음 문자 중 하나를 포함하는 이름 또는 값을 사용하는 경우:!#$%&'()*+/:<=>?@[]^`{|}그들은 그 도서관들과 다르게 처리될 것입니다.쿠를설정경우쿠다키음인로다니됩으로 됩니다.%{HEX}쿠키를 읽고 있다면 암호를 해독해야 합니다.

예를 들어, 반면에.email=name@domain.com쿠키이며, 이는 이 를 " 한효쿠입다니키"로 합니다.email=name%40domain.com사용 중인 경우 디코딩에 문제가 발생할 수 있습니다.%쿠키 안에 있습니다.망가질 거예요.를 들어, 예를들어다음같은쿠있습다니키가과▁that:다있▁for▁was▁cookie습니▁your▁example키쿠,가.secretagentlevel=50%007and50%006 되다secretagentlevel=507and506그것은 가장자리 케이스이지만 라이브러리를 전환할 때 주의해야 할 사항입니다.

됩니다.path=/에 대한 전송됩니다.", "URL" 및 "URL"은 다음과 같습니다.

직접 이한값직인하거나디딩코다면수사있다습니용할음을려코러하딩을 하면 됩니다.encodeURIComponent또는decodeURIComponent각각 다음과 같다.


참조:


추가 정보:

포괄적인 기능 집합이 있는 "쿠키" npm 모듈을 사용할 수 있습니다.

문서 및 예제 위치:
https://github.com/jed/://github.com/jed/cookies

쿠키 값에 '='이 있는 쿠키와 함께 쿠키 분할기를 작동시키려면:

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;
};

개별 쿠키를 가져오려면:

get_cookies(request)['my_cookie']

쿠키는 HTTP 헤더를 통해 전송됩니다.
요청 헤더를 구문 분석하고 응답 헤더만 넣으면 됩니다.

노드에서 쿠키를 관리하기 위한 깔끔한 복사 앤 붙여넣기 패치가 있습니다.아름다움을 위해 커피스크립트로 하겠습니다.

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

이제 다음과 같이 쿠키를 처리할 수 있습니다.

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

일부 ES5/6 마법 및 ReGEx 마법 사용

여기 쿠키를 읽고 키의 개체로 전환하는 옵션이 있습니다. 클라이언트 측의 값 쌍은 서버 측에서도 사용할 수 있습니다.

메모에 만약있다가 있다면,=그 가치로, 걱정하지 마세요.에 만약있다가 ,=핵심은, 낙원에서의 문제입니다.

추가 노트어떤 사람들은 가독성을 주장할 수 있으니 당신이 원하는 대로 그것을 분해하세요.

아이 라이크 노트오류 처리기(시도 횟수)를 추가해도 문제가 없습니다.

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

enter image description here

무슨 일입니까?

iLikeCookies()를 키를나 것입니다눌쿠로 입니다.;(뒤 공백):

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

한 그런다째 다 음 해 발 로 으 분 합 할 니 생 번 첫 고 하 매 핑 어 당 를 이 레 ▁by ▁then ▁first 니합 다 ▁and 할 ▁map 분 ▁that ▁split rence ▁occur ▁of ▁we=정규식 캡처 부모 사용:

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

그런 다음 Entries의 친구 Object.를 사용하여 키, Val 쌍의 개체로 만듭니다.

안 돼요.

cookie lib을 사용하여 들어오는 여러 쿠키를 구문 분석할 수 있으므로 예외 사례에 대해 걱정할 필요가 없습니다.

var cookies = cookie.parse('foo=bar; equation=E%3Dmc%5E2');
// { foo: 'bar', equation: 'E=mc^2' }

쿠키를 작성하려면 다음과 같이 할 수 있습니다.

response.writeHead(200, {
    "Set-Cookie": `mycookie=cookie`,
    "Content-Type": `text/plain`
});

만약 당신이 무엇이 있는지 신경쓰지 않는다면.cookie사용하기만 하면 다음과 같은 깔끔한 접근 방식을 사용해 보십시오(인기 노드 모듈).

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

나는 이 간단한 함수를 그냥 통과했습니다.req.headers.cookie쿠키 이름

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

    arrOfCookies.forEach(element => {
        if(element.includes(name)){
            yourCookie = element.replace(name+'=','')
        }
    });
    return yourCookie
}

이 질문에 대한 답이 이미 많이 있다는 것을 알지만, 여기 네이티브 JS에서 만들어진 기능이 있습니다.

function parseCookies(cookieHeader) {
    var cookies = {};
    cookieHeader
        .split(";")
        .map(str => str.replace("=", "\u0000")
        .split("\u0000"))
        .forEach(x => cookies[x[0]] = x[1]); 

    return cookies;
}

document.cookie 문자열을 가져오는 것으로 시작합니다.모든 키-값 쌍은 세미콜론(;)으로 구분됩니다.따라서 첫 번째 단계는 각 키-값 쌍으로 문자열을 나누는 것입니다.

그 후 함수는 "="의 첫 번째 인스턴스를 나머지 문자열에 없는 임의의 문자로 대체합니다. 이 함수에 대해 NULL 문자(\u0000)를 사용하기로 결정했습니다.이제 키-값 쌍을 두 조각으로 분할할 수 있습니다.이제 두 조각을 JSON으로 결합할 수 있습니다.

쿠키 설정

let key = "eyJhbGciOiJ...";
response.setHeader('Set-Cookie', `key=${key}; HttpOnly`);

쿠키 가져오기

let val = request.headers.cookie.split("=")[1];

먼저 쿠키를 만든 다음(예를 들어 쿠키 내부에 토큰을 랩핑했습니다) 응답으로 설정해야 합니다.쿠키를 다음 방법으로 사용하려면 cookieParser를 설치합니다.

app.use(cookieParser());

브라우저는 '리소스' 탭에 저장되며 초기 URL을 기본으로 사용한 후 모든 요청에 사용됩니다.

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

서버 측의 요청에서 쿠키를 얻는 것도 쉽습니다.요청 개체의 'cookie' 속성을 호출하여 요청에서 쿠키를 추출해야 합니다.

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

언급URL : https://stackoverflow.com/questions/3393854/get-and-set-a-single-cookie-with-node-js-http-server

반응형