Deno + TypeScriptでCookieをセキュアにしてヘッダーを改良（供養）



## あらかじめ

__👻GitHubのレポジトリにするまでもない内容なのでここで供養させてください...👻__

_☠️この記事では、Deno(TypeScript)を使用してCookieをセキュアにし、ヘッダーを改良する方法についてお粗末にご紹介します☠️_

## 実行

今回、denolandでcookie.tsをバージョン指定せずにimportすると最新版を取得します。
> ➡️実行時の最新版URL: https://deno.land/std@0.192.0/http/cookie.ts

実行コマンド

```typescript
deno run main.ts
```

## セキュアにしたCookieをtoStringした.ver (需要: 不明)

```typescript: main.ts
import { Cookie } from "https://deno.land/std/http/cookie.ts";

const createSecureCookie = (cookie: Cookie): string => {
  const defaultOptions: Cookie = {
    name: cookie.name ?? "nothing",
    value: cookie.value ?? "nothing",
    path: cookie.path ?? "nothing",
    expires: new Date(Date.now() + 2 * 60 * 60 * 1000), // After 2 hours from now.
    secure: true,
    httpOnly: true,
    maxAge: 7200, // 7200 seconds (2 hours).
  };

  const mergedCookie: Cookie = { ...defaultOptions, ...cookie };

  let mergedCookie_toString = ``;
  if (mergedCookie.name) {
    mergedCookie_toString += `name=${mergedCookie.name}`;
  }

  if (mergedCookie.value) {
    mergedCookie_toString += `; value=${mergedCookie.value}`;
  }

  if (mergedCookie.expires) {
    mergedCookie_toString += `; Expires=${mergedCookie.expires.toUTCString()}`;
  }

  if (mergedCookie.maxAge) {
    mergedCookie_toString += `; Max-Age=${mergedCookie.maxAge}`;
  }

  if (mergedCookie.secure) {
    mergedCookie_toString += `; Secure`;
  }

  if (mergedCookie.httpOnly) {
    mergedCookie_toString += `; HttpOnly`;
  }

  if (mergedCookie.path) {
    mergedCookie_toString += `; Path=${mergedCookie.path}`;
  }

  return mergedCookie_toString;
};

const cookiesList: Cookie[] = [
  { name: "lulu", value: "meow", path: "/" },
  { name: "me", value: "bye", path: "../" },
];

for (const cookie of cookiesList) {
  const secure_cookie = createSecureCookie(cookie);
  const secure_headers = new Headers(); 
  secure_headers.set("Set-Cookie", secure_cookie); //(name: string, value: string)
}
```

### Summary

ソースコード内では、`createSecureCookie`という関数を定義しています。この関数は、与えられたCookie情報を基にセキュアなCookieヘッダーを生成します。デフォルトのオプションとCookie情報をマージし、最終的なCookie情報を作成します。その後、Headers（）のvalue：stringであることを考慮して、_`(文字列にわざわざ置き換えて)`_ セキュアなCookieヘッダーを含むヘッダーオブジェクトを作成します。


### 変数secure_headersの出力結果
```typescript: Headers(name: "set-cookie", value: $(mergedCookie_toString))
Headers {
  "set-cookie": "name=lulu; value=meow; Expires=Sun, 25 Jun 2023 13:00:01 GMT; Max-Age=7200; Secure; HttpOnly; Path=/"
}
Headers {
  "set-cookie": "name=me; value=bye; Expires=Sun, 25 Jun 2023 13:00:01 GMT; Max-Age=7200; Secure; HttpOnly; Path=../"
}
```

## セキュアにしたCookieのみ返す.ver (需要: まだ高そう)
😼Cookieをセキュアにしてそのままreturnさせるなら、わざわざstringに変換しなくて良い😼



```typescript: main.ts
import { Cookie } from "https://deno.land/std/http/cookie.ts";

const createSecureCookie = (cookie: Cookie): string => {
  const defaultOptions: Cookie = {
    name: cookie.name ?? "nothing",
    value: cookie.value ?? "nothing",
    path: cookie.path ?? "nothing",
    expires: new Date(Date.now() + 2 * 60 * 60 * 1000), // After 2 hours from now.
    secure: true,
    httpOnly: true,
    maxAge: 7200, // 7200 seconds (2 hours).
  };

  const mergedCookie: Cookie = { ...defaultOptions, ...cookie };
  return mergedCookie;
};

const cookiesList = [
  { name: "lulu", value: "meow", path: "/" },
  { name: "me", value: "bye", path: "../" },
];

for (const cookie of cookiesList) {
  const secure_cookie = createSecureCookie(cookie); 
  // console.log(secure_cookie);
}

```

### Summary

ソースコード内では、`createSecureCookie`という関数を定義しています。この関数は、与えられたCookie情報を基にセキュアなCookieヘッダーを生成します。デフォルトのオプションとCookie情報をマージし、最終的なCookie情報を作成します **(終)**


### 変数secure_cookieの出力結果`(変数mergedCookieと同じです)`
```typescript: (cookie: Cookie)
{
  name: "lulu",
  value: "meow",
  path: "/",
  expires: 2023-06-25T13:37:51.722Z,
  secure: true,
  httpOnly: true,
  maxAge: 7200
}
{
  name: "me",
  value: "bye",
  path: "../",
  expires: 2023-06-25T13:37:51.725Z,
  secure: true,
  httpOnly: true,
  maxAge: 7200
}

```

## コラム(解説)

以上がDeno(TypeScript)でCookieをセキュアにしてヘッダーを改良する方法の解説でした。
ここからは、セキュアにCookieを上書きする仕組みについて簡潔に説明します。

`const mergedCookie: Cookie = { ...defaultOptions, ...cookie };`は、オブジェクトのスプレッド構文を使用して、`defaultOptionsオブジェクト`と`cookieオブジェクト`を**結合**して`新しいオブジェクトmergedCookie`を作成しています。

具体的には、`defaultOptionsオブジェクト`のプロパティと値がmergedCookieにコピーされ、その後に`cookieオブジェクト`のプロパティと値が**上書き**されます。これにより、defaultOptionsのデフォルトのプロパティ値を持つ`mergedCookieオブジェクト`が作成されています。