JavaScript
Node.js
TypeScript
Firebase
FirebaseCloudFunctions

Firebase Hosting でCloud Functions for Firebase を使用するとCookieが使用できない件の対応

2019/03/14追記

どうもローカルのサーバならOKなんですが、デプロイした後やってみるとやっぱりダメみたいです。addCookie側はOKなんですが、

$ curl http://[hostingサーバ名]/getCookie -H 'Cookie: state=6; state1=7'

$

うーん、詰みましたorz。登り電文にcookieは乗るのですが、サーバ側関数では取得できず。。。

firebase serve ってローカルでやったときだけうまくいくようでした。ごめんなさい。。

2019/03/14追記 ここまで

Cloud Functions for Firebase をFirebase Hosting 経由で使っていて Cookieをつかおうとしたら、Cloud Functions による動的コンテンツの配信 この制約に引っかかるようで、Cookieを下ろしてくれないみたい。

うーん、とりあえず下記のとおりresponse.setHeader('Cache-Control', 'private')で解決できるぽいので、備忘メモ。


index.ts

import * as functions from 'firebase-functions'

import * as cookie from 'cookie'

export const addCookie = functions.https.onRequest((request, response) => {
response.setHeader('Cache-Control', 'private') // Hosting経由だと、これがないとset cookieが削除される
_addCookie(response, 'key', 'value')
response.send('Hello from Firebase!')
})

export const getCookie = functions.https.onRequest((request, response) => {
// response.setHeader('Cache-Control', 'private')
const cookies = cookie.parse(request.headers.cookie || '')
const sessionState = cookies.state
response.send(sessionState)
})

function _addCookie (res, key, value) {
const expiresIn = 60 * 60 * 24
const options = { maxAge: expiresIn, httpOnly: true }
// const options = { maxAge: expiresIn, httpOnly: true, secure: true }
res.setHeader('Set-Cookie', cookie.serialize(key, value, options))
}


$ curl http://localhost:5000/addCookie -i

HTTP/1.1 200 OK
x-powered-by: Express
cache-control: private
pragma: no-cache
expires: 0
set-cookie: key=value; Max-Age=86400; HttpOnly ← ちゃんとおろしてる
content-type: text/html; charset=utf-8
content-length: 20
etag: W/"14-z3iZXchEt5DVWZKsMncy8Wl4KSQ"
date: Sun, 10 Mar 2019 02:18:40 GMT
connection: close
vary: Accept-Encoding, Authorization, Cookie

Hello from Firebase!

$ curl http://localhost:5000/getCookie -H 'Cookie: state=6; state1=7'
6 // サーバ上での取得も問題なし
$

サーバからのCookieの受領も、サーバへのCookieのアップも問題なさそうですね。

この事象と「ブラウザはアクセスURLが localhost だと、下ろしてくる set-cookieを無視する?」事象が合わさって、ずいぶんトラブルシューティングに時間がかかりましたorz。localhost問題の方は結局 /etc/hosts で client.example.com などホスト名をつけて対応。

$ cat /etc/hosts

##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting. Do not change this entry.
##
127.0.0.1 localhost
255.255.255.255 broadcasthost
::1 localhost
127.0.0.1 client.example.com
$

おつかれさまでした。