概要
LIFFアプリをFirebase Authenticationで認証する方法です。
前提知識
- LIFFアプリの概要
- typescript
- React
- Nextjs
流れ
- LIFFアプリにログイン
- フロント側でLIFFの情報
id token
を取得 - 取得した
id token
を認証用apiにpost - サーバー側で
id token
の有効性を検証する - 検証したらFirebase Authenticationでカスタムトークンを発行して返却
- サーバーから送られてきたカスタムトークンでFirebase authにログインする
サーバー側のコード
Firebase Authenticationのカスタムトークンを発行するAPIをNextjs api routesで作成する
https://nextjs.org/docs/api-routes/introduction
LINE APIの公式ドキュメントから仕様は確認できます
pages/api/verify.ts
const Verify = async (req, res) => {
// id tokenを取得
const idToken = req.body.idToken;
// id tokenの有効性を検証する
const response = await fetch('https://api.line.me/oauth2/v2.1/verify', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: qs.stringify({
id_token: idToken,
client_id: process.env.LIFF_CHANNEL_ID,
}),
});
const data = await response.json();
if (response.status !== 200) {
// IDトークンが有効ではない場合
res.status(400).send(data.error);
return;
}
// LINE IDでfirebaseトークンを発行して返却
const token = await auth.createCustomToken(data.sub);
res.status(200).send(token);
};
フロント側のコードの一部(React)
useEffect(() => {
if (!liff.isLoggedIn()) {
// LIFFログインしていなかったらリダイレクト
router.push('/login');
return;
}
auth.onAuthStateChanged(user => {
if (user) {
setCurrentUser(user);
} else {
// 作成したapiにidトークンをpost
fetch('/api/verify', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
idToken: liff.getIDToken(),
}),
}).then(response => {
response.text().then(data => {
// 返ってきたカスタムトークンでFirebase authにログイン
auth.signInWithCustomToken(data).then(response => {
const user = response.user;
setCurrentUser(user);
});
});
});
}
});
}, []);