最初に結論
cookie使うときは __session
ってkey以外は切り捨てられるぞ気をつけろ!
やろうとしたこと
- firebase+nodejs勉強もかねて、認証系の実装をしてみた
- サインイン処理をしたあと、一定期間サインイン状態をキープしたい
- cookieで情報持ってればいいか!ドキュメントを参考にしよう
参考:https://firebase.google.com/docs/auth/admin/manage-cookies?hl=ja#create_session_cookie
こんなかんじの実装?
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から情報を引き出せるようになったぞヤッター
※ 実装例は動作確認してないですすみません。