HTTPCookieのしくみを学ぶ

Cookieは、セッションを可能にし、一般にナビゲーション中にユーザーを認識するため、Webの基本的な部分です。

前書き

Cookieを使用することで、サーバーとブラウザーの間で情報を交換して、ユーザーセッションをカスタマイズする方法を提供したり、サーバーがリクエスト間でユーザーを認識したりすることができます。

HTTPはステートレスです。つまり、サーバーへのすべてのリクエストの発信元はまったく同じであり、サーバーは、リクエストが以前にリクエストを行ったクライアントからのものか、それとも新しいものかを判断できません。

Cookieは、HTTPリクエストの開始時にブラウザからサーバーに送信され、サーバーから返送されます。サーバーはコンテンツを編集できます。

Cookieは基本的に、セッションIDを保存するために使用されます

以前は、代替手段がなかったため、Cookieを使用してさまざまな種類のデータを保存していました。しかし、最近ではWebストレージAPI(ローカルストレージとセッションストレージ)とIndexedDB、はるかに優れた選択肢があります。

特にCookieは、保持できるデータの制限が非常に低いため、画像やCSSなどのアセットのリクエストを含むサーバーへのHTTPリクエストごとにCookieが送受信されるためです。JavaScriptファイル。

Cookieには長い歴史があり、1994年に最初のバージョンがあり、時間の経過とともに複数のRFCリビジョンで標準化されました。

RFCはRequestfor Commentsの略で、インターネットの標準を設定する責任を負うエンティティであるInternet Engineering Task Force(IETF)によって標準が定義される方法です。

Cookieの最新の仕様は、RFC 6265, which is dated 2011.

クッキーの制限

  • クッキーは保存することしかできません4KBのデータ
  • クッキーはドメイン専用。サイトは設定したCookieのみを読み取ることができ、他のドメインのCookieは読み取ることができません
  • ドメインごとに最大20のCookieの制限を設定できます(ただし、正確な数は特定のブラウザーの実装によって異なります)
  • Cookieの総数には制限があります(ただし、正確な数は特定のブラウザーの実装によって異なります)。この数を超えると、新しいCookieが古いCookieに置き換わります。

Cookieは、サーバー側またはクライアント側で設定または読み取ることができます。

クライアント側では、Cookieはドキュメントオブジェクトなのでdocument.cookie

クッキーを設定する

Cookieを設定する最も簡単な例は次のとおりです。

document.cookie = 'name=Flavio'

これにより、既存のCookieに新しいCookieが追加されます(既存のCookieは上書きされません)

Cookieの値はURLエンコードされている必要がありますencodeURIComponent()、Cookie値で無効な空白、コンマ、またはセミコロンが含まれていないことを確認します。

他に何も設定しない場合、ブラウザを閉じるとCookieの有効期限が切れます。これを防ぐには、UTC形式で表された有効期限を追加します(Mon, 26 Mar 2018 17:04:05 UTC

document.cookie = 'name=Flavio; expires=Mon, 26 Mar 2018 17:04:05 UTC'

24時間で有効期限が切れるCookieを設定するための簡単なJavaScriptスニペットは次のとおりです。

const date = new Date()
date.setHours(date.getHours() + 24)
document.cookie = 'name=Flavio; expires=' + date.toUTCString()

または、max-age秒数で表される有効期限を設定するパラメーター:

document.cookie = 'name=Flavio; max-age=3600' //expires in 60 minutes
document.cookie = 'name=Flavio; max-age=31536000' //expires in 1 year

ザ・pathパラメータはCookieのドキュメントの場所を指定するため、特定のパスに割り当てられ、パスが現在のドキュメントの場所または親と一致する場合にのみサーバーに送信されます。

document.cookie = 'name=Flavio; path=/dashboard'

このCookieはに送信されます/dashboard/dashboard/todayおよびその他のサブURL/dashboard/、しかしオンではない/posts例えば。

パスを設定しない場合、デフォルトで現在のドキュメントの場所になります。つまり、内部ページからグローバルCookieを適用するには、次のように指定する必要があります。path=/

ザ・domainCookieのサブドメインを指定するために使用できます。

document.cookie = 'name=Flavio; domain=mysite.com;'

設定されていない場合、サブドメインを使用している場合でも、デフォルトでホスト部分になります(subdomain.mydomain.comの場合、デフォルトでmydomain.comに設定されます)。ドメインCookieはサブドメインに含まれています。

Secure

追加するSecureパラメータは、CookieがHTTPSを介してのみ安全に送信され、暗号化されていないHTTP接続を介して送信されないようにします。

document.cookie = 'name=Flavio; Secure;'

これによってCookieが安全になるわけではないことに注意してください。Cookieに機密情報を追加することは常に避けてください。

HttpOnly

1つの有用なパラメータはHttpOnly、を介してCookieにアクセスできなくなりますdocument.cookieAPIなので、サーバーでのみ編集できます。

document.cookie = 'name=Flavio; Secure; HttpOnly'

SameSite

SameSite、残念ながら、まだすべてのブラウザでサポートされているわけではありません(ただし、多くのブラウザでサポートされています!https://caniuse.com/#feat=same-site-cookie-attribute、サーバーは、Cookieがクロスサイトリクエストで送信されるのではなく、Cookieドメインをオリジンとして持つリソースでのみ送信されることを要求できます。これは、CSRF(クロスサイトリクエストフォージェリ)攻撃のリスクを軽減するのに大いに役立ちます。

Cookieの値を更新するには、Cookie名に新しい値を割り当てるだけです。

document.cookie = 'name=Flavio2'

値の更新と同様に、有効期限を更新するには、値を新しいものに再割り当てしますexpiresまたはmax-ageプロパティ:

document.cookie = 'name=Flavio; max-age=31536000' //expires in 1 year

そもそも追加したパラメータも忘れずに追加してください。pathまたはdomain

Cookieを削除するには、その値の設定を解除し、過去の日付を渡します。

document.cookie = 'name=; expires=Thu, 01 Jan 1970 00:00:00 UTC;'

(そして、あなたがそれを設定するために使用したすべてのパラメーターで)

Cookieの値にアクセスする

Cookieにアクセスするには、ルックアップdocument.cookie

const cookies = document.cookie

これにより、ページに設定されているすべてのCookieがセミコロンで区切られた文字列が返されます。

'name1=Flavio1; name2=Flavio2; name3=Flavio3'
//ES5
if (
  document.cookie.split(';').filter(item => {
    return item.indexOf('name=') >= 0
  }).length
) {
  //name exists
}

//ES2016 if ( document.cookie.split(’;’).filter(item => { return item.includes(‘name=’) }).length ) { //name exists }

抽象化ライブラリ

Cookieを管理するためのより使いやすいAPIを提供するさまざまなライブラリがいくつかあります。それらの1つはhttps://github.com/js-cookie/js-cookie、IE7までをサポートし、GitHubにたくさんの星があります(これは常に良いです)。

その使用例のいくつか:

Cookies.set('name', 'value')
Cookies.set('name', 'value', {
  expires: 7,
  path: '',
  domain: 'subdomain.site.com',
  secure: true
})

Cookies.get(‘name’) // => ‘value’ Cookies.remove(‘name’)

//JSON Cookies.set(‘name’, { name: ‘Flavio’ }) Cookies.getJSON(‘name’) // => { name: ‘Flavio’ }

それまたはネイティブCookieAPIを使用しますか?

すべては、ユーザーごとにダウンロードするキロバイトを追加することになるので、それはあなたの選択です。

サーバー側でCookieを使用する

HTTPサーバーの構築に使用されるすべての環境でCookieを操作できます。これは、Cookieが最新のWebの柱であり、Cookieなしでは構築できないためです。

PHPには$ _COOKIEがありますGoにはCookie機能がありますnet/http標準ライブラリ

等々。

Node.jsで例を見てみましょう

Express.jsを使用する場合、res.cookieAPI:

res.cookie('name1', '1Flavio', {
  domain: '.example.com',
  path: '/admin',
  secure: true
})
res.cookie('name2', 'Flavio2', {
  expires: new Date(Date.now() + 900000),
  httpOnly: true
})
res.cookie('name3', 'Flavio3', { maxAge: 900000, httpOnly: true })

//takes care of serializing JSON res.cookie(‘name4’, { items: [1, 2, 3] }, { maxAge: 900000 })

Cookieを解析するには、https://github.com/expressjs/cookie-parserミドルウェア。すべてのリクエストオブジェクトには、Cookie情報が含まれますreq.cookieプロパティ:

req.cookies.name //Flavio
req.cookies.name1 //Flavio1

を使用してCookieを作成する場合signed: true

res.cookie('name5', 'Flavio5', { signed: true })

それらはで利用可能になりますreq.signedCookies代わりにオブジェクト。署名されたCookieは、クライアントでの変更から保護されます。 Cookie値の署名に使用される署名により、クライアントがCookie値を変更したかどうかをサーバー側で確実に知ることができます。

https://github.com/expressjs/sessionそしてhttps://github.com/expressjs/cookie-sessionは、Cookieベースの認証を構築するための2つの異なるミドルウェアオプションであり、どちらを使用するかはニーズによって異なります。

ブラウザDevToolsを使用してCookieを検査します

のすべてのブラウザDevToolsCookieを検査および編集するためのインターフェースを提供します。

クロム

Chrome devtools cookies

Firefox

Firefox devtools cookies

サファリ

Safari devtools cookies

クッキーの代替品

Web上で認証とセッションを構築する唯一の方法はCookieですか?

番号!最近人気が出た技術がありますJSONWebトークン((JWT)、 これはトークンベースの認証

私の無料ダウンロードJavaScriptビギナーズハンドブック


その他のブラウザチュートリアル: