28
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

firebaseでcookieを使おうとしてハマった話

Posted at

最初に結論

cookie使うときは __session ってkey以外は切り捨てられるぞ気をつけろ!

やろうとしたこと

こんなかんじの実装?


const functions = require('firebase-functions');
const express = require('express');
const cookieParser = require('cookie-parser');
const admin = require('firebase-admin');
const firebase = require('firebase/auth');
admin.initializeApp({...});
firebase.initializeApp({...});

const app = express();
app.use(cookieParser());

// サインイン処理
function signin(email, pass) {
    return new Promize((resolve, reject) => {
        firebase.auth().signInWithEmailAndPassword(email, pass)
        .then((result) => { firebase.auth().onAuthStatechanged(resolge); })
        .catch(reject);
    });
};

const expiresIn = 60*60*24*5*1000; // 5days
app.post('/signin', (req, res) => {
    var email = req.body.email;
    var pass = req.body.pass;

    signin(email, pass)
    .then((user) => {
        user.getIdToken()
        .then((token) => {
            admin.auth().createSessionCookie(token, {expiresIn})
            .then((sessionCookie) => {
                // cookieに詰め込む
                res.cookie('session', sessionCookie, {maxAge: expiresIn});
                res.redirect('/mypage');
        });
    })
    .catch((error) => {
        res.send('error:'+error);
    });
};

app.get('/mypage', (req, res) => {
    var sessionCookie = req.cookies.session;
    console.log('sessionCookie:'+sessionCookie); // cookieから取り出した内容をとりあえず表示してみる

    // cookieの情報から認証確認
    admin.auth().verifySessionCookie(sessionCookie, true)
    .then((decodedClaims) => {
        var uid = decodedClaims.uid;
        res.send('signed in by uid('+uid+')'); // singin してるのはこのuidさんだよ
    })
    .catch((error) => {
        res.send('error:'+error);
    });
};

exports.app = functions.https.onRequest(app);

ローカルでcookie認証できてることを確認する

firebase serve してlocalhost:5000にアクセス
email&passで認証して、その認証がキープされてることが確認できた!

よし、これでOKだろう!

さぁ firebase deploy して、publicな環境で確認してみよう!

が、ダメ!

おかしいな?

localではできたのにdeployした先ではcookieが空っぽになってるやん!
firebaseのドキュメントを参考に作ったんだけどなぁ

実はこんな罠があった

結構な時間悩んでいたけど、実は罠が潜んでいた
ドキュメントの実装例には session というkeyでcookieに情報を詰め込んでいたが、これが NG

__session というkey以外の情報は削除されてしまうようだった
参考:https://firebase.google.com/docs/hosting/manage-cache?hl=ja#using_cookies

へぇ~localとpublicで挙動違うんだなぁ

修正版


const expiresIn = 60*60*24*5*1000; // 5days
app.post('/signin', (req, res) => {
    var email = req.body.email;
    var pass = req.body.pass;

    signin(email, pass)
    .then((user) => {
        user.getIdToken()
        .then((token) => {
            admin.auth().createSessionCookie(token, {expiresIn})
            .then((sessionCookie) => {
                // cookieに詰め込む
                res.cookie('__session', sessionCookie, {maxAge: expiresIn});// ★keyを__sessionにした
                res.redirect('/mypage');
        });
    })
    .catch((error) => {
        res.send('error:'+error);
    });
};

app.get('/mypage', (req, res) => {
    var sessionCookie = req.cookies.__session;// ★keyを__sessionにした
    console.log('sessionCookie:'+sessionCookie); // cookieから取り出した内容をとりあえず表示してみる

    // cookieの情報から認証確認
    admin.auth().verifySessionCookie(sessionCookie, true)
    .then((decodedClaims) => {
        var uid = decodedClaims.uid;
        res.send('signed in by uid('+uid+')'); // singin してるのはこのuidさんだよ
    })
    .catch((error) => {
        res.send('error:'+error);
    });
};

これでなんとかcookieから情報を引き出せるようになったぞヤッター
※ 実装例は動作確認してないですすみません。

28
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?