TL;DR æ¬æžã§ã¯ãFirebase ããã³ Firestore ã§ãªã¢ã«ã¿ã€ã Web ãã£ãããäœãæ¹æ³ãåŠã³ãŸããããã«ãèªèšŒã·ã¹ãã ãšã㊠Firebase ã¢ããªã§ Auth0 ã䜿ãæ¹æ³ïŒãããŠããã䜿çšããçç±ïŒãåŠã³ãŸããããããã¯ãããžãŒãšçµ±åã®æå§ããšããŠã確å®ã«ã¡ãã»ãŒãžã Firestore ã«ä¿åãïŒFirebase ãæäŸãããªã¢ã«ã¿ã€ã ã®ããŒã¿ããŒã¹ïŒããŠãŒã¶ãŒã Auth0 ãéããŠèªèšŒã§ããç°¡åãªãªã¢ã«ã¿ã€ã Web ãã£ãããæ§ç¯ããŸããå¿ èŠã§ããã°ããã® GitHub ãªããžããªã«ããèšäºã§äœæããæåŸã®ã³ãŒããã芧ãã ããã
âFirebase ããã³ Firestore ã§ãªã¢ã«ã¿ã€ã Web ãã£ãããäœãæ¹æ³ãåŠã³ãŸããããâ
ããããã€ãŒããã
åææ¡ä»¶
以äžã®ã¹ãããã«åŸãã«ã¯ãNode.js ããã³ JavaScript ã«ã€ããŠã®åºæ¬çãªç解ãæ·±ããŠãã ããããµãŒããŒåŽã«ã¯ Node.js ãããããžã§ã¯ãã®ããã±ãŒãž ãããŒãžã£ãŒã«ã¯ NPM ã䜿çšããŸãããã£ãŠãäž¡æ¹ã®ãœãããŠã§ã¢ãããŒã«ã«ã«ã€ã³ã¹ããŒã«ããå¿ èŠããããŸãããããã®ããŒã«ãã€ã³ã¹ããŒã«ããŠããªããã°ããã®ãªãœãŒã¹ã確èªããŠãã ããïŒNPM ã«ã¯ Node.js ãå«ãŸããŠããŸãïŒã
Firebase ãšã¯äœãïŒ
Firebase ã¯ãã©ãããã©ãŒã ã§ãWeb ããã³ã¢ãã€ã« ã¢ããªã±ãŒã·ã§ã³ãçŽ æ©ãäœæã§ããŸãããã®ãã©ãããã©ãŒã ã¯ç¹å®ã®æ©èœãæäŸããããã«ãããžã§ã¯ãã«ç°¡åã«çµ±åã§ãããµãŒãã¹ãæäŸããŸããããããµãŒãã¹ã®ã²ãšã€ã¯Â Cloud Firestore ã§ãGoogle ãæäŸãããã¬ãã·ãã«ãã¹ã±ãŒã©ãã«ããªã¢ã«ã¿ã€ã 㪠NoSQL ããŒã¿ããŒã¹ã§ããæ¬æžã§ã¯ Firestore ã䜿ã£ãŠãã£ããã¢ããªã±ãŒã·ã§ã³ã®ãªã¢ã«ã¿ã€ã ããŒã¿ããŒã¹ãèšå®ããŸãã
Firebase ãš Auth0 ãäžç·ã«äœ¿çšããã®ã¯ãªããïŒ
Firebase ã«ã¯èªèšŒæ©èœãå«ãŸããŠããããšãè¯ãç¹ã§ãããã ããåè¿°ããããã«ãèªèšŒæ¹æ³ãšã㊠Firebase ã€ã³ã¹ã¿ã³ã¹ã§ Auth0 ãæ§æããŠãããŸããããã念é ã«ãFirebase ã䜿ã£ãŠ Auth0 ã®ãããªå€éšèªèšŒãããã€ããŒã䜿ãå¿ èŠæ§ã«ã€ããŠçåã«æãããŠãããããããŸããã
Auth0 ã䜿ã£ãŠ Firebase ãµãŒãã¹ãå®å šã«ããããšã¯ãå¿ ããã Firebase èªèšŒã䜿çšããªããšããããšã§ã¯ãããŸãããå®éã®ãšãããFirebase ã¯ã«ã¹ã¿ã ããŒã¯ã³ã䜿ãã«ã¹ã¿ã èªèšŒã®ã¢ãããŒããæäŸããŠãããããã«ãã£ãŠ Firebase ãå®å šã«ããããã« Firebase ããã§ã«æäŸãããã«ãã€ã³èªèšŒã¢ãããŒãã䜿ãããããåžæã® ID ãããã€ããŒã䜿ãããšãå¯èœã«ãªããŸããã§ã¯ãFirebase ã®ãã«ãã€ã³èªèšŒæ¹æ³ããã Auth0 ã䜿ã£ãã«ã¹ã¿ã èªèšŒã¢ãããŒãã䜿ãã®ã¯ãªãã§ããããïŒãã®çåã«å¯Ÿããåçã¯è€æ°ãããŸãã
åºæ¬ç㪠GoogleãTwitterãFacebook ãªã©ã®ãœãŒã·ã£ã«ãããã€ããŒã®ã»ãã«è€æ°ã®ãœãŒã·ã£ã«ãããã€ããŒãã¢ããªã±ãŒã·ã§ã³ã«çµ±åããå¿ èŠããããããããŸãããAuth0 æœèšã§ã¯äœçŸãšããç°ãªããœãŒã·ã£ã«ãããã€ããŒã䜿ã£ãŠããŸãã
ãŠãŒã¶ãŒã®æŽ»åãžã®æŽå¯ãé«ããå¿ èŠããããããããŸãããAuth0 ã§ã¯çŸç¶ãç¥ãããã«ã匷åãªã¬ããŒããåæãæäŸããŠããŸãã
å ç¢ãªãŠãŒã¶ãŒç®¡çã·ã¹ãã ãå¿ èŠãããããŸããã
ãŸããå€èŠçŽ èªèšŒããã¹ã¯ãŒã ã»ãã¥ãªãã£éåããŸãã¯ç°åžžæ€åºãªã©ã®æ©èœã䜿ã£ãŠã¢ããªã±ãŒã·ã§ã³ã®ã»ãã¥ãªãã£ã匷åããå¿ èŠããããããããŸããã
èªèšŒããã³èªèšŒãã€ãã©ã€ã³ã®å段éãå®å šã«ã«ã¹ã¿ãã€ãºããå¿ èŠããããããããŸããã
ãŸãšãããšãã¢ããªã±ãŒã·ã§ã³ãä¿¡é Œæ§ã®é«ãè€éãªèªèšŒæ¹æ³ãå¿ èŠãšããã®ã§ããã°ïŒå€§æµã¯å¿ èŠãšããïŒãã«ã¹ã¿ã èªèšŒã¢ãããŒãã䜿çšãã¹ãã§ãããããããããšã«ãFirebase ã¯ãã®ä»ã®èªèšŒãœãªã¥ãŒã·ã§ã³ããã®ãµãŒãã¹ã«çµ±åããæ¹æ³ãæäŸããŠããŸããããã«ã€ããŠã®è©³çŽ°ã¯æ¬æžã§èª¬æããŠããŸãã
âAuth0 ã Firebase ã¢ããªã±ãŒã·ã§ã³ã§ã«ã¹ã¿ã èªèšŒãããã€ããŒãšããŠäœ¿çšãããšãããã«ä¿¡é Œæ§ã®é«ãã¢ããªã«ããããšãã§ããŸããâ
ããããã€ãŒããã
ã©ã®ããã«ã㊠Firebase ãš Auth0 ãé£æºããããïŒ
Firebase ãš Auth0 ãé£æºãããããšã«ã€ããŠã¯åŸã»ã©èª¬æããŸããããšãŠãç°¡åã§ãããã®æµãå šäœã¯ Auth0 ã䜿ã£ãŠã¢ããªã±ãŒã·ã§ã³ïŒãã€ãã£ãã¢ããªãWeb ã¢ããªãSPA ãªã©ã«ãããããïŒãå®å šã«ããããšããå§ãŸããŸãããŠãŒã¶ãŒãèªèšŒããã»ã¹ã®äžè²«ãšã㊠Auth0 ãéããŠèªèšŒãããšããã¢ããªã¯ Auth0 ã§å®å šã«ãããããã¯ãšã³ã API ã«ãªã¯ãšã¹ãçºè¡ããããã«äœ¿çšããããã¯ããŒã¯ã³ïŒ
idTokens
 ããã³/ãŸãã¯Â accessTokens
ïŒãååŸããŸããããã API ã¯ãªã¯ãšã¹ããåŠçããŠããéããããã®ããŒã¯ã³ãååŸããããããä¿¡é Œããããããã€ããŒãçºè¡ãããã®ãïŒãã®å Žå Auth0ïŒãæå¹æéãåããŠããªãããæ€èšŒããŸãããããã®ããŒã¯ã³ãæå¹ã§ããã°ãAPI ã¯ããã«å¿ããŠãªã¯ãšã¹ããå®è£
ããŸããäžèšã®æµãã¯ã¢ããªã±ãŒã·ã§ã³ã Auth0 ã§å®å šã«ãããšãã«éåžžçºçããã¹ãããã§ããã§ã¯ãFirebase ããã®ã¬ã·ãã«è¿œå ããã«ã¯ãããã¯ãšã³ã API ïŒAuth0 ã§å®å šã«ãªã£ãŠããïŒã«ãšã³ããã€ã³ããäœæããŠã«ã¹ã¿ã Firebase ããŒã¯ã³ãçæããŸãããããããããã¯ãšã³ãããããããŒã¯ã³ã®äœæãçµãã£ãããã¯ã©ã€ã¢ã³ã ã¢ããªãããããè¿ããŠããããã䜿ã£ãŠFirebase ãžã®èªèšŒã«äœ¿çšããŸãã
ããã§ã®ããžãã¯ã¯ãããã¯ãšã³ã API ãšããã³ããšã³ã ã¯ã©ã€ã¢ã³ãã Auth0 ã«ãã£ãŠå®å šã«ãªã£ãŠããã®ã§ããŠãŒã¶ãŒã¯ Auth0 ãéããŠãŸãèªèšŒãããã®ã§ããã°ãã«ã¹ã¿ã Firebase ããŒã¯ã³ã®ã¿ãååŸã§ããŸãããã®æäœã«ãé¢å¿ãããæ¹ã¯ãåŸã»ã©ãã®æµãå šäœãå®è£ ããŸãã®ã§ããå¿é ã¯ãããŸããã
Firebase ãèšå®ãã
Firebase ã䜿çšããããã«ã¯ãFirebase ã¢ã«ãŠã³ãã«ãµã€ã³ã¢ããããå¿ èŠããããŸãããããçµãã£ããã次ã«ããããšã¯ Firebase ãããžã§ã¯ããäœæããããšã§ãããã®ããã«ã¯Firebase ã³ã³ãœãŒã«ã«ç§»åããŠãããžã§ã¯ãã®è¿œå ãã¯ãªãã¯ããŸãããããã¯ãªãã¯ãããšãFirebase ã¯ãããžã§ã¯ãã®åå ïŒãFirestore ãã£ããã¢ããªãã®ãããªååïŒãå®çŸ©ãããã©ãŒã ã衚瀺ãããŸãã®ã§ã2ã€ã®ãã§ãã¯ããã¯ã¹ããã£ãã¯ããŸãããããçµãã£ããããããžã§ã¯ãã®äœæ ãã¿ã³ãã¯ãªãã¯ããŸãã
æ°ç§åŸãFirebase ã¯ãããžã§ã¯ãã®äœæãçµãããããžã§ã¯ãã®æŠèŠ ããŒãžã«ãªãã€ã¬ã¯ããããŸããããããÂ
</>
 ã®ãããªãã¿ã³ãã¯ãªãã¯ãããšãFirebase ããããã£ã§ãããã¢ããã衚瀺ãããŸãããã®ãããã¢ãããã apiKey
ãauthDomain
ãããã³ projectId
 å€ããã®ãããã¢ããããè€åãããããã©ããã«ä¿åããŸãã ãããã¯ã¯ã©ã€ã¢ã³ãã¢ããªã§ Firebase ãæ§æããŠãããšãã«åŸã»ã©äœ¿çšããŸããããã§ãFirestore ãæ§æããŠãããŸããäžè¿°ããããã«ãããããæ§æããã¯ã©ã€ã¢ã³ã ã¢ããªã±ãŒã·ã§ã³ã¯ Firestore ã䜿ã£ãŠãã£ãã ã¡ãã»ãŒãžãä¿åããŸãããã£ãŠãæ°èŠããŒã¿ããŒã¹ã Firebase ã³ã³ãœãŒã«ã«äœãå¿ èŠããããŸãããã®ããã«ã¯ã瞊ã¡ãã¥ãŒã«ããããŒã¿ããŒã¹ ãªãã·ã§ã³ãã¯ãªãã¯ããŸãããããããããŒã¿ããŒã¹ã®äœæ ãã¿ã³ãã¯ãªãã¯ãããã¹ãã¢ãŒãã§éå§ ãªãã·ã§ã³ãéžæããæå¹ ãã¯ãªãã¯ããŸããæ°ç§ãã£ãããFirestore ããŒã¿ããŒã¹ã䜿çšããçšæãã§ããŸããã
ãããããFirestore ããŒã¿ããŒã¹ãå®å šã«ããã«ã¯ãæ°èŠ Firestore ããŒã¿ããŒã¹ã®èŠå ã»ã¯ã·ã§ã³ã«ç§»åããŠæ¢å®ã®èŠåãšæ¬¡ã亀æããŸãã
service cloud.firestore { match /databases/{database}/documents { match /messages/{message} { allow read: if true; allow write: if request.auth.uid != null; } } }
åºæ¬çã«ããã®èŠåã¯èª°ããããŒã¿ããŒã¹ããèªã¿åãããšãã§ãããïŒ
èªã¿åããèš±å¯ïŒçå®ã§ããã°
ïŒãèªèšŒãŠãŒã¶ãŒã®ã¿ããããæžãåãïŒæžãåããèš±å¯ïŒrequest.auth.uid != null
ã§ããã°ïŒããšãã§ããããšãæ瀺ããŸãããã®èŠåãèšçœ®ããã®ã§ãçºè¡ ãã¿ã³ãæŒããŠå³åº§ã«èŠåãæå¹ã«ããŸãããµãŒãã¹ ã¢ã«ãŠã³ãç§å¯ããŒãçæãã
ã«ã¹ã¿ã èªèšŒã¢ãããŒãã䜿çšããŠããã®ã§ãFirebase ã§èªèšŒã«äœ¿çšããã«ã¹ã¿ã ããŒã¯ã³ãäœæããå¿ èŠããããŸããFirebase ã¯ãããã«ã¹ã¿ã ããŒã¯ã³ãäœæããã®ã«åœ¹ç«ã€ç®¡çè SDK ãæäŸããŸããããã® SDK ãæ©èœããã«ã¯ããµãŒãã¹ã¢ã«ãŠã³ã ã«é¢ããè³æ Œæ å ±ïŒãã¡ã€ã«åœ¢æ ïŒãäžããå¿ èŠããããŸãããã®ã¢ã«ãŠã³ããäœæããŠãããè³æ Œæ å ±ïŒãã®ãã¡ã€ã«ïŒãååŸããã«ã¯ããããžã§ã¯ãã®æŠèŠ ã®æšªã«ããå°ããªæ¯è»ã®ã¢ã€ã³ã³ãã¯ãªãã¯ãããããããããžã§ã¯ãèšå® ãã¯ãªãã¯ããŸãã
ãããã¯ãªãã¯ããããFirebase ã¯ãããžã§ã¯ãã®èšå®ããŒãžã«ãªãã€ã¬ã¯ãããŸãããããããŒããããããµãŒãã¹ ã¢ã«ãŠã³ã ã¿ãã«ç§»åããŠÂ Firebase 管çè SDK ãªãã·ã§ã³ãéžæããŸãããããããæ°ããç§å¯ããŒã®çæ ãã¿ã³ãã¯ãªãã¯ããŸããããã«ãFirebase ã¯ãµãŒãã¹ã¢ã«ãŠã³ãã®è³æ Œæ å ±ãšå ±ã« JSON ãã¡ã€ã«ãéä¿¡ããŸããçŸæç¹ã§ã¯ããã®ãã¡ã€ã«ãå®å šãªå Žæã«ä¿åããŸããã®ã¡ã»ã©ããã®è³æ Œæ å ±ãå¿ èŠã«ãªããŸãã
æ³šïŒ ãµãŒãã¹ã¢ã«ãŠã³ãã®ç§å¯ããŒãå«ã JSON ãã¡ã€ã«ã¯ éåžžã«æ©å¯æ§ã®é«ããã® ãªã®ã§ãGitHub ã®ãããªå ¬å ±ãªããžããªãšã¯é¢ããŠä¿åããŠãã ããã
Auth0 ãèšå®ãã
åæ§ã«ãAuth0 ã䜿çšããã«ã¯ãã¢ã«ãŠã³ããå¿ èŠã§ããã¢ã«ãŠã³ãããªãæ¹ã¯ãããããç¡æã§ãµã€ã³ã¢ãã ããŠãã ããã
ã¢ã«ãŠã³ãã®äœæãçµãã£ããããã·ã¥ããŒãã®ã¢ããªã±ãŒã·ã§ã³Â ã»ã¯ã·ã§ã³ã«ç§»åããã¢ããªã±ãŒã·ã§ã³ã®äœæ ãã¯ãªãã¯ããŸãããã®ãã¿ã³ãã¯ãªãã¯ãããšãAuth0 ããããã¢ããã衚瀺ããããã§ã¢ããªã±ãŒã·ã§ã³ã®åå ãšïŒåã³ããFirestore ãã£ããã¢ããªãã®ååã䜿ããŸãïŒã¢ããªã®ã¿ã€ããäŒããªããã°ãªããŸããããªã¢ã«ã¿ã€ã ãã£ããã¢ããªïŒåèªã¿èŸŒã¿ã«äŸåããªãã¢ããªïŒãæ§ç¯ãããšããã·ã³ã°ã«ããŒãž Web ã¢ããªã±ãŒã·ã§ã³ ãéžæããå¿ èŠããããŸãããããããäœæ ãã¿ã³ãã¯ãªãã¯ãããšãAuth0 ã¯æ°èŠã¢ããªã±ãŒã·ã§ã³ã®ã¯ã€ã㯠ã¹ã¿ãŒã ã»ã¯ã·ã§ã³ã«ãªãã€ã¬ã¯ãããŸãããããããèšå® ã¿ããã¯ãªãã¯ããããç¹å®ãã£ãŒã«ããå€æŽããŸãã
èšå® ã¿ãã«ç§»åããããèš±å¯ãããã³ãŒã«ãã㯠URL ãã£ãŒã«ããæ¢ãã
http://localhost:3001/
 ãããã«å ããŸãããã®ãã£ãŒã«ãã¯ãèªèšŒåŸããŠãŒã¶ãŒãæ§æãããã®ïŒãã®å Žåã¯http://localhost:3001/
ïŒã«ãªãã€ã¬ã¯ããããããã« Auth0 ã«æ瀺ããŸããããã ãã§ãããã㯠Auth0 ã«ãã£ãŠå®è£
ãããã»ãã¥ãªãã£å¯Ÿçã§ãä»ã®ã¢ããªããŠãŒã¶ãŒã®ã¢ããªã«çæãããããŒã¯ã³ãååŸããªãããšãä¿èšŒããŸãããã®ãã£ãŒã«ããæºããããããã®ããŒãžã®äžéšã«ããå€æŽã®ä¿å ãã¿ã³ãã¯ãªãã¯ããŠæ§æãæŽæ°ããŸãããåŸã»ã©ãã®ããŒãžããæ å ±ãã³ããŒããã®ã§ãããã¯éããªãã§ãã ããã
Web ãµãŒããŒãã¹ãã£ãã©ãŒã«ãã£ã³ã°ãã
Auth0 ããã³ Firebase ã®èšå®ãçµãã£ãã®ã§ã次ã«ããããšã¯ã¢ããªã±ãŒã·ã§ã³ã®ãã£ã¬ã¯ããªãäœæããããšã§ããã³ã³ãã¥ãŒã¿ãŒãèµ·åããŠæ¬¡ã®ã³ãã³ããå®è¡ããŸãã
# ãããžã§ã¯ãã«ç§»åããŸã cd firestore-web-chat # ããã NPM ããã±ãŒãžãšããŠåæåããŸã npm init -y
ãã®ã³ãã³ãã¯Â package.json ãã¡ã€ã«ãåæåãããã¹ãŠã®ãããžã§ã¯ãã®äŸåé¢ä¿ã远跡ããã®ã«åœ¹ç«ã¡ãŸãããã®ãã¡ã€ã«ã«ã¯ã¢ããªã±ãŒã·ã§ã³ã«ã€ããŠã®æå¹ãªæ å ±ãå«ã¿ãŸãã
ããã§ãããã¯ãšã³ãã®äŸåé¢ä¿ãã€ã³ã¹ããŒã«ããå¿ èŠããããŸãããµãŒããŒåŽã«ã¢ããªã±ãŒã·ã§ã³ã®ç¹å®éšåãæ§ç¯ããã®ã«ããã±ãŒãžã®äžéšã䜿çšããŸãã以äžã®ã³ãã³ããå®è¡ããŠæ¬¡ã®ããã±ãŒãžãã€ã³ã¹ããŒã«ããŸãã
npm install express cors express-jwt jwks-rsa firebase-admin
以äžã¯ãããããã±ãŒãžãäœããããããã©ã®ããã«åœ¹ç«ã€ãã«ã€ããŠã®ç°¡åãªèŠçŽã§ãã
ïŒExpress 㯠Node.js ãã¬ãŒã ã¯ãŒã¯ã§ãNode.js ã䜿ã£ãŠ Web ã¢ããªã±ãŒã·ã§ã³ã®æ§ç¯ãç°¡åã«ãªããŸããexpress
ïŒãã®ããã±ãŒãžã¯ Express ããã«ãŠã§ã¢ãšããŠæ©èœãããµãŒããŒäžã®ã¯ãã¹ ãªãªãžã³ ãªãœãŒã¹å ±æãæå¹ã«ããŸããcors
ïŒJSON Web Tokens (JWT) ã䜿ã£ãŠ HTTP ãªã¯ãšã¹ããèªèšŒããã«ã¯ãã®ããã±ãŒãžã䜿ããŸãããã®ããã±ãŒãžã¯ HTTP ãªã¯ãšã¹ãã®express-jwt
ããããŒã«éä¿¡ããããŒã¯ã³(JWT)ãæœåºããåºæ¬çã«ãã®ããŒã¯ã³ãæ€èšŒããããšãã Express ããã«ãŠã§ã¢ã§ããAuthorization
ïŒãã®ããã±ãŒãžã¯ãããããŒã¯ã³ã眲åããã®ã«äœ¿ã JWKS (JSON Web Key Set) ãšã³ããã€ã³ããããã®ããŒãååŸããã®ã«äœ¿ããŸããjwks-rsa
ïŒãã®ããã±ãŒãžã¯ãµãŒããŒãªã©ç¹æš©ã®ããç°å¢ãã Firebase ãµãŒãã¹ãšã®å¯Ÿè©±ãå¯èœã«ããŸããä»åã¯ç¹ã«ã«ã¹ã¿ã èªèšŒããŒã¯ã³ãäœãã®ã«ãã®ããã±ãŒãžã䜿çšããŸããfirebase-admin
ã«ã¹ã¿ã èªèšŒããŒã¯ã³ãäœã
ããã§ããã¯ãšã³ã ãµãŒããŒã®ã¹ãã£ãã©ãŒã«ãã£ã³ã°ãçµãã£ãã®ã§ããããžã§ã¯ãã®ã³ãŒãã£ã³ã°ãå§ããããšãã§ããŸããããã§ããããžã§ã¯ã ã«ãŒã ãã£ã¬ã¯ããªã«Â src ãšãããã©ã«ããŒãäœããŸãããã®ãã©ã«ããŒã«ã¯ãã¹ãŠã®ã¢ããªã±ãŒã·ã§ã³ ã³ãŒããå«ãŸããŸãïŒãµãŒããŒåŽãšã¯ã©ã€ã¢ã³ãåŽã®äž¡æ¹ïŒãããã§ããã®æ°ãããã©ã«ããŒå ã«Â server.js ãšãããã¡ã€ã«ãäœãã次ã®ã³ãŒããããã«æ¿å ¥ããŸãã
// src/server.js const express = require('express'); const cors = require('cors'); const jwt = require('express-jwt'); const jwks = require('jwks-rsa'); const firebaseAdmin = require('firebase-admin'); const path = require('path'); const app = express(); app.use(cors()); app.use('/', express.static(path.join(__dirname, 'public'))); const jwtCheck = jwt({ secret: jwks.expressJwtSecret({ cache: true, rateLimit: true, jwksRequestsPerMinute: 5, jwksUri: `https://${process.env.AUTH0_DOMAIN}/.well-known/jwks.json` }), audience: process.env.AUTH0_API_AUDIENCE, issuer: `https://${process.env.AUTH0_DOMAIN}/`, algorithm: 'RS256' });
äžèšã®ã³ãŒã ã¹ããããã§æåã«å®è¡ããã®ã¯ã以åã€ã³ã¹ããŒã«ããããã±ãŒãžãã€ã³ããŒãããããšã§ããããã®åŸã
express
 ãåæåãããµãŒããŒãç°ãªããªãªãžã³ããã®ãªã¯ãšã¹ããåãå
¥ããããã«Â cors
 ãæ§æããŸãããããããããã®çŽåŸã«2ã€ã®éèŠãªããšãçºçããŸããExpress ãµãŒããŒã«ããŠãŒã¶ãŒã䜿çšã§ããéçãã¡ã€ã«ãšããŠ
 ãšãããã£ã¬ã¯ããªã®äžã®ãã¡ã€ã«ãåŠçããããã«äŒããŸãïŒãã®ãã£ã¬ã¯ããªã¯éããªãäœããŸãïŒãpublic
ã¯ã©ã€ã¢ã³ãããéä¿¡ããã JSON Web Token ãæ€èšŒããÂ
ïŒjwtCheck
ã®å©ããåŸãŠïŒãšããããã«ãŠã§ã¢ãäœããŸãããexpress-jwt
ããã«è©³ããã¯ãã¯ã©ã€ã¢ã³ãããµãŒããŒäžã®ç¹å®ã«ãŒãã«ãªã¯ãšã¹ããããšããããŒã¯ã³ïŒAuth0 ã®çœ²åæžã¿ïŒãšå ±ã«Â
Authorization
 ããããŒã«éä¿¡ãããŸããjwtCheck
 ããã«ãŠã§ã¢ã¯ãã®ããŒã¯ã³ãå±éããæå¹ãã確èªããŸãããã®ããŒã¯ã³ãç¡å¹ãªå ŽåããŸãã¯å±å®³ãåããŠããå Žåãå³åº§ã«æåŠãããŸããããã§ãªããã°ããã®ããŒã¯ã³ã¯ãã³ãŒãããããã€ããŒãã¯æ¬¡ã®ããã«ãŠã§ã¢ã«éä¿¡ãããŸããããã§ããã®ããã«ãŠã§ã¢ã¯ã©ã®ããã«ããŠããŒã¯ã³ã®æå¹æ§ã確蚌ããã®ããçåã«æããããããããŸãããç¹å®ã®æ§æããããã£ã䜿ã£ãŠããã®ããã«ãŠã§ã¢ãããŒã¯ã³ã®æ€èšŒãæ£ç¢ºã«ç¥ãããããã«æ§æããŸãã
ïŒããã¯å ¬éããŒã§ãããŒã¯ã³ã確èª/æ€èšŒããããã«äœ¿çšããŸããã¯ã©ã€ã¢ã³ãããéä¿¡ãããããŒã¯ã³ã¯ Auth0 ã®çœ²åæžã¿ããŒã¯ã³ã ãšäºæž¬ãããŸããAuth0 ã¯ãAuth0 çºè¡ã®ããŒã¯ã³ã眲åããããã«äœ¿çšãããæå·åããŒãè¡šã JWK (JSON Web Key) ãå«ã¿ãJSON ãã¡ã€ã«ã«ãã€ã³ãããåããã³ãã®ãšã³ããã€ã³ãïŒãŠãŒã¶ãŒã®ãã®ãå«ãïŒãå ¬éããŸãããã® JWK ã¯ããŒã¯ã³ã®ä¿¡é Œæ§ãæ€èšŒããããã«äœ¿çšãããå ¬éããŒãå«ã¿ãŸããjwks-rsaïŒÂ ããã±ãŒãžã¯ããã³ãã« Auth0 ã«ãã£ãŠå ¬éããããšã³ããã€ã³ããããã®ããŒãååŸããããã«äœ¿çšããŸããsecret
ïŒå¯Ÿè±¡ãŠãŒã¶ãŒã¯ Auth0Âaudience
 ã䜿ã£ãŠ JWT ã®åä¿¡è ãèå¥ããŸããclientID
ïŒãã㯠JWT ãçºè¡ããåœäºè ãäžæã«èå¥ãã URI ã§ããAuth0 ãçºè¡ãã ID ããŒã¯ã³ã®å Žåã¯ãã㯠Auth0 ã¢ããªã±ãŒã·ã§ã³ã®issuer
ã§ãïŒäŸïŒdomain
ïŒãblog-samples.auth0.com
ïŒãã㯠Auth0 ã JWT ã眲åããããã«äœ¿çšããã¢ã«ãŽãªãºã ã瀺ããŸããalgorithm
 ã¯ããã§ã¯ãããŒã¯ã³ã眲åããããã«äœ¿çšãããŸãããã®ã¢ãããŒãã¯ç§å¯ããŒã¯é察称ã¢ã«ãŽãªãºã ã䜿çšããŠããŸããã€ãŸã ç§å¯ããŒã¯ JWT ã眲åããããã«äœ¿çšããå ¬éããŒã¯ãã®çœ²åãæ€èšŒããããã«äœ¿çšããããšãæå³ããŸãããã®ã¢ã«ãŽãªãºã ã«é¢ãã詳现ã¯ãã®èšäºãã芧ãã ãããRS256
ããã§ãã©ã®ããã« Auth0 ã䜿ã£ãŠ Express ã¢ããªãå®å šã«ããããåŠãã ã®ã§ã
src
 ãã£ã¬ã¯ããªã«Â firebase
 ãšããæ°ãããã©ã«ããŒãäœããŸãããã®ãã©ã«ããŒã«ã¯ã以å Firebase ããããŠã³ããŒããã JSON ãã¡ã€ã«ãé
眮ããŸãããã㯠Firebase ãµãŒãã¹ ã¢ã«ãŠã³ãã®è³æ Œæ
å ±ãå«ããã¡ã€ã«ã§ãããã® JSON ãã¡ã€ã«ãã¬ããžããªã«ã³ããããããŠããªãããã«ãåã firebase
 ãã©ã«ããŒã«Â .gitignore
 ãã¡ã€ã«ãäœããçæãã JSON ãã¡ã€ã«ã®ååãããã«å ããèªã¿ãããããããã« JSON ãã¡ã€ã«ã firebase-key.json
 ã«ååãå€æŽããŸãã# src/firebase/.gitignore firebase-key.json
ã§ã¯ã次ã«ã¯ã©ã€ã¢ã³ããéä¿¡ããããŒã¯ã³ãæ€èšŒããããã«æ§æããèªèšŒããã«ãŠã§ã¢ã䜿ã Express ã«ãŒããèšå®ããŸããã¯ã©ã€ã¢ã³ãã® Firestore ãšã®éä¿¡ãå¯èœã«ãã ã«ã¹ã¿ã Firebase ããŒã¯ã³ãäœãããã« Firebase Admin SDK ã䜿ããŸãã次ã®ã³ãŒããÂ
server.js
ãã¡ã€ã«ã®äžéšã«è²Œãä»ããŸãã// src/server.js // ... æ®ãã¯ãã®ãŸãŸã«ããŸã ... const serviceAccount = require('./firebase/firebase-key'); firebaseAdmin.initializeApp({ credential: firebaseAdmin.credential.cert(serviceAccount), databaseURL: `https://${serviceAccount.project_id}.firebaseio.com` }); app.get('/firebase', jwtCheck, async (req, res) => { const {sub: uid} = req.user; try { const firebaseToken = await firebaseAdmin.auth().createCustomToken(uid); res.json({firebaseToken}); } catch (err) { res.status(500).send({ message: 'Firebase ããŒã¯ã³ãååŸãããšãã«ãšã©ãŒãçºçããŸããã', error: err }); } }); app.listen(3001, () => console.log('Server running on localhost:3001'));
äžèšã§ãŸãããã®ã¯ãFirebase ããããŠã³ããŒãããè³æ Œæ å ±ã§Â Firebase Admin SDK ãåæåããŸããããã®åŸã
/firebase
 ã®äžã« Express ã«ãŒããäœæããã®ã§ãã¯ã©ã€ã¢ã³ã㯠Firestore ãšéä¿¡ããããã«ã«ã¹ã¿ã ããŒã¯ã³ãååŸã§ããŸããAuth0 ãéããŠèªèšŒããããŠãŒã¶ãŒã®ã¿ã確å®ã«ã«ã¹ã¿ã Firebase ããŒã¯ã³ãååŸã§ããããã«ãjwtCheck
 ã /firebase
route ã«ãã©ã°ã€ã³ããŸãããã¯ã©ã€ã¢ã³ããããã®ã«ãŒã¿ãžã®åãªã¯ãšã¹ãã§ãããã«ãŠã§ã¢ã¯ããŒã¯ã³ãæœåºãããããæ€èšŒããŸãããã®ããŒã¯ã³ãæå¹ã§ããã°ãããŒã¯ã³ãéã¶ãã€ããŒãã¯Â req.user
 ãªããžã§ã¯ãã«èªã¿èŸŒãŸãã次ã®ããã«ãŠã§ã¢ã«éä¿¡ãããŸããããã§ãªããã°ããã®ã-ã¯ã³ãç¡å¹ãªå Žåãã¯ã©ã€ã¢ã³ãã«ãšã©ãŒã¡ãã»ãŒãžãã¹ããŒããããã®åŸã®ã¢ã¯ã»ã¹ã¯æåŠãããŸããreq.user
 ãªããžã§ã¯ãäžã®ãã€ããŒãã¯Â sub
 ãšããããããã£ãå«ã¿ãåãŠãŒã¶ãŒãäžæã«èå¥ããããã«äœ¿çšãããŸããFirebase Admin SDK ã¯ã«ã¹ã¿ã ããŒã¯ã³ãäœãããã«ãã®äžæã®èå¥åã䜿ãããã®ã«ã¹ã¿ã ããŒã¯ã³ã¯ã¯ã©ã€ã¢ã³ãã«æ»ãããŸãããããããã¯ã©ã€ã¢ã³ãã¯ãã®ããŒã¯ã³ã䜿ã£ãŠ Firebase ã§èªèšŒ/æ€èšŒããŸãããµãŒããŒåŽã¯ããã ãã§ãã次ã«ãã¯ã©ã€ã¢ã³ãåŽã®ã¢ããªã±ãŒã·ã§ã³ãèšå®ããŸããäžèšã®æ©èœã«ã¯Â
async
ããŒã¯ãŒãã§ãã¬ãã£ãã¯ã¹ãä»ããŠããããšãåãããŸãããã㯠Promise ã§éåææäœãè¡ãããããšãè¡šãããã«äœ¿çšããŸãã éåæ/åŸ
æ©ã«ã€ããŠéŠŽæã¿ã®ãªãæ¹ã¯ãã¡ããã芧ãã ããããŠãŒã¶ãŒ ã€ã³ã¿ãŒãã§ã€ã¹ãæ§ç¯ãã
æ¬ç« ã§ã¯ãç°¡åãªãªã¢ã«ã¿ã€ã ãã£ãã ã¢ããªã±ãŒã·ã§ã³ã§ããã¯ã©ã€ã¢ã³ã ã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããŸãããŸããããªããã°ãªããªãããšã¯ UI ãèšå®ããããšã§ããã§ãããã
src
 ãã£ã¬ã¯ããªã«Â public
ãšãããã©ã«ããŒãäœããŸãããã®ãã£ã¬ã¯ããªã«ã¯ãã¹ãŠã®ã¯ã©ã€ã¢ã³ãåŽã®ã³ãŒããå«ãŸããŸãããã®åŸãindex.html
 ãšãããã¡ã€ã«ãäœããpublic
 ãã©ã«ããŒã«å
¥ããŸãããããçµãã£ããã次ã®ã³ãŒãã index.html
 ãã¡ã€ã«ã«ã³ããŒ&ããŒã¹ãããŸãã<!doctype html> <html lang="en" class="h-100"> <head> <!-- å¿ é ã¡ã¿ã¿ã° --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"> <title>Auth0 ããã³ Firebase ãã£ãã ã¢ããª</title> </head> <body class="h-100"> <div class="container-fluid d-flex flex-column h-100"> <div class="row bg-primary p-2 text-white" style="z-index: 10000; min-height: 60px;"> <div class="col-12 p-2"> <div id="profile" class="font-weight-bold"></div> <button id="sign-in" type="button" class="btn">Sign In</button> <button id="sign-out" type="button" class="btn">Sign Out</button> </div> </div> <div class="row flex-fill"> <div id="chat-area" class="col-12 d-flex flex-column-reverse" style="overflow-y: auto;"> </div> </div> <div class="row bg-dark p-2" style="min-height: 55px;"> <div class="col-12"> <input type="text" class="form-control" id="message" aria-describedby="message-help" placeholder="Enter your message" disabled> </div> </div> </div> <script src="https://www.gstatic.com/firebasejs/5.3.0/firebase-app.js"></script> <script src="https://www.gstatic.com/firebasejs/5.3.0/firebase-auth.js"></script> <script src="https://www.gstatic.com/firebasejs/5.3.0/firebase-firestore.js"></script> <script src="https://cdn.auth0.com/js/auth0/9.7.3/auth0.min.js"></script> <script src="/app/auth0.js"></script> <script src="/app/firebase.js"></script> <script src="/app/index.js"></script> </body> </html>
äžèšã«ã¯é£ãããã®ã¯ãããŸããããã£ãã ã¢ããªã±ãŒã·ã§ã³ã®ã¹ã¿ã€ã«ãèšå®ãBootstrapã®å©ããåŸãŠïŒãAuth0 ããã³ FirebaseïŒ
auth0.min.js
 ããã³3ã€ã®Â firebase-*.js
 ã¹ã¯ãªããïŒãæäŸããå€éšã©ã€ãã©ãªãæãã¹ã¯ãªãã ã¿ã°ãè¿œå ããŠããã ãã§ãããããã©ã€ãã©ãªã¯ä»¥åäœæãã Auth0 ããã³ Firebase ã¢ããªã±ãŒã·ã§ã³/ã€ã³ã¹ã¿ã³ã¹ãåæåãã察話ã§ããããã«ããŸãããŸãããã®ãã¡ã€ã«ã¯æ¬¡ã®ããã«ã¢ããªã® UI ã®äž»ãªèŠçŽ ãå®çŸ©ããŸãã
ïŒãŠãŒã¶ãŒã®èªèšŒãæå¹ã«ãããã¿ã³ãsign-in
ïŒãŠãŒã¶ãŒã®ãµã€ã³ã¢ãŠããæå¹ã«ãããã¿ã³ãsign-out
ïŒãªã¢ã«ã¿ã€ã ã¡ãã»ãŒãžã衚瀺ãããé åãchat-area
ïŒãŠãŒã¶ãŒãã¡ãã»ãŒãžãã¿ã€ãããå ¥åããã¹ããmessage
æåŸã«ãããŒã«ã« ãã¡ã€ã«ã«ãã€ã³ãããè¿œå ã®ã¹ã¯ãªãã ã¿ã°ãè¿œå ããŸãïŒ
/app/auth0.js
ã/app/firebase.js
ãããã³Â /app/index.js
ïŒãããããã¡ã€ã«ã¯æ¬¡ã®ã»ã¯ã·ã§ã³ã§äœæããŸããã¯ã©ã€ã¢ã³ãã« Auth0 ãæ§æãã
ããã§ã¯ãAuth0 ãšã®éä¿¡ãæ§ç¯ããã¯ã©ã€ã¢ã³ãåŽã¢ããªãå¯èœã«ãããã¡ã€ã«ãäœæããŸãïŒAuth0 ãèªèšŒãµãŒããŒãšããŠäœ¿çšãããªã©ïŒããã®ããã«ã¯ã
app
 ãšããå¥ã®ãã£ã¬ã¯ããªã /src/public
 ã®äžã«äœããauth0.js
 ãšãããã¡ã€ã«ããã®æ°ãããã£ã¬ã¯ããªã«äœããŸãããã㧠Auth0 ãåæåãæ§æããŸããããã§ãã³ãŒãããã®ãã¡ã€ã«ã«è²Œãä»ããŸãã// ./src/public/app/auth0.js let _auth0Client = null; let _idToken = null; let _profile = null; class Auth0Client { constructor() { _auth0Client = new auth0.WebAuth({ domain: 'YOUR_APP_DOMAIN', audience: 'https://YOUR_APP_DOMAIN/userinfo', clientID: 'YOUR_APP_CLIENTID', redirectUri: 'http://localhost:3001/', responseType: 'token id_token', scope: 'openid profile' }); } getIdToken() { return _idToken; } getProfile() { return _profile; } handleCallback() { return new Promise((resolve, reject) => { _auth0Client.parseHash(async (err, authResult) => { window.location.hash = ''; if (err) return reject(err); if (!authResult || !authResult.idToken) { // not an authentication request return resolve(false); } _idToken = authResult.idToken; _profile = authResult.idTokenPayload; return resolve(true); }); }); } signIn() { _auth0Client.authorize(); } signOut() { _idToken = null; _profile = null; } } const auth0Client = new Auth0Client();
ã芧ã®ããã«ã
Auth0Client
 ãšããã¯ã©ã¹ãå®çŸ©ãããã®ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã§ãã auth0Client
 ãšããã°ããŒãã«å®æ°ãå®çŸ©ããŸãããã®ã¯ã©ã¹ïŒããã³ãã®ã€ã³ã¹ã¿ã³ã¹ïŒã¯èªèšŒãããŒãåŠçããç¹å®ã®ã¡ãœãããå®è£
ããŸãã
ïŒã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ãŒã¯Âconstructor
 ã©ã€ãã©ãªãç¬èªã® Auth0 è³æ Œæ å ±ã§æ§æããŸããauth0-js
ïŒãã®ã¡ãœããã¯ãŠãŒã¶ãŒã Auth0 ã«ãªãã€ã¬ã¯ããèªèšŒã¡ãœãããéžæã§ããããã«ããŠãèªèšŒããã»ã¹ãåæåããŸããsignIn
ïŒãã®ã¡ãœããã¯ÂsignOut
 ããã³Â_idToken
ãã¯ãªãŒãã³ã°ããŠçŸåšã®ãŠãŒã¶ãŒ ã»ãã·ã§ã³ãåãé€ããŸãã_profile
ïŒãã®ã¡ãœããã¯ããŒã¯ã³ããªãããçŸåšã®ããŒãžã® URL ããã·ã¥ã確èªããŸãïŒããã¯å®éãhandleCallback
ã§è¡ãããŸãïŒããŠãŒã¶ãŒèªèšŒãçµãã£ãããAuth0 㯠URL ã®ããã·ã¥ãã©ã°ã¡ã³ãäžã®ãã®æ å ±ïŒããŒã¯ã³ïŒãšäžç·ã«ãããã¢ããªã«æ»ããŸãããããããŒã¯ã³ããã§ããããã«ã¯ããã®ã¡ãœãããåŒã³åºããããã«å¿ããŠã¯ã©ã€ã¢ã³ãåŽã»ãã·ã§ã³ãèšå®ããŸãïŒäŸïŒÂparseHash
 ããã³Â_idToken
 å€æ°ãèšå®ããïŒã_profile
 ããã³ÂgetIdToken
ïŒãããã¡ãœããã¯ã¢ããªããŠãŒã¶ãŒæ å ±ã䜿çšã§ããããã«ããŸããgetProfile
æ³šïŒ ãã¹ãŠã®Â
 ãã¬ãŒã¹ãã«ããŒã®çºçããã³ÂYOUR_APP_DOMAIN
 ãã¬ãŒã¹ãã«ããŒã®çºçãšç¬èªã® Auth0 ããããã£ã眮ãæããŸããYOUR_APP_CLIENTID
ã眮ãæããã«ã¯ã以åã«äœæãã Auth0 ã¢ããªã±ãŒã·ã§ã³ã®ãã¡ã€ã³ ãã£ãŒã«ãã«è¡šç€ºã®å€ãã³ããŒããŸãïŒäŸïŒYOUR_APP_DOMAIN
ïŒãblog-samples.auth0.com
ã眮ãæããã«ã¯ãAuth0 ã¢ããªã±ãŒã·ã§ã³ã®ã¯ã©ã€ã¢ã³ã ID ãã£ãŒã«ãã䜿ããŸããYOUR_APP_CLIENTID
ã¯ã©ã€ã¢ã³ãã« Firebase ãæ§æãã
ãããŸã§ã§ããã®ã§ã次ã«è¡ãããšã¯ Firebase ãã¯ã©ã€ã¢ã³ãåŽã¢ããªã«æ§æããããšã§ãããã®ããã«ã¯ã
firebase.js
ãšããæ°ãããã¡ã€ã«ã app
 ãã£ã¬ã¯ããªãŒã«äœããŸããããããã次ã®ã³ãŒãããã®ãã¡ã€ã«ã«è¿œå ããŸãã// ./src/public/app/firebase.js let _messagesDb = null; class Firebase { constructor() { firebase.initializeApp({ apiKey: 'YOUR_PROJECT_APIKEY', authDomain: 'YOUR_PROJECT_AUTHDOMAIN', projectId: 'YOUR_PROJECT_ID', }); // initialize Firestore through Firebase _messagesDb = firebase.firestore(); // disable deprecated features _messagesDb.settings({ timestampsInSnapshots: true }); } async addMessage(message) { const createdAt = new Date(); const author = firebase.auth().currentUser.displayName; return await _messagesDb.collection('messages').add({ author, createdAt, message, }); } getCurrentUser() { return firebase.auth().currentUser; } async updateProfile(profile) { if (!firebase.auth().currentUser) return; await firebase.auth().currentUser.updateProfile({ displayName: profile.name, photoURL: profile.picture, }); } async signOut() { await firebase.auth().signOut(); } }
åã®ã»ã¯ã·ã§ã³ã§å®è¡ããããã«ãã¯ã©ã¹ãäœæããŠãã®ãã¡ã€ã«ã§ãµãŒãããŒã㣠ãµãŒãã¹ãšå¯Ÿè©±ããã®ã«åœ¹ç«ã€ã¯ã©ã¹ãäœæããŸãïŒãã®å ŽåãAuth0 ã§ã¯ãªã FirebaseïŒããã®æ°ããã¹ã¯ãªããã¯æ¬¡ã®ããã«æ©èœããŸãã
ïŒã³ã³ã¹ãã©ã¯ã¿ãŒæ©èœã§ Firebase ããã³ Firestore ã®äž¡æ¹ãåæåããŸããconstructor
ïŒã¯ã©ã€ã¢ã³ãåŽã¢ããªãæå¹ã«ã㊠Firestore ããŒã¿ããŒã¹ã«ãã£ãã ã¡ãã»ãŒãžãè¿œå ããããã«ãã®ã¡ãœãããå®çŸ©ããŸãããŠãŒã¶ãŒããã£ãã ã¡ãã»ãŒãžãéä¿¡ãããšãã¯ãã€ã§ãã¢ããªã¯é¢æ°ãåŒã³åºããŠåŒæ°ãšããŠã¡ãã»ãŒãžããã¹ããŸããã芧ã®ããã«ãã¡ããµâãžãããŒã¿ããŒã¹ã§äžŠã¹æ¿ãããããÂaddMessage
 ãÂcreatedAt
 ã®ãããªãã®ä»ã®ãããã㣠ãã¡ãã»ãŒãžã«è¿œå ããŸããauthor
å€æ°ãå®çŸ©ãããã®Âauthor
 ãæ¥ãå Žæããå°ãåŠã³ãŸããdisplayName
ïŒãã®ã¡ãœãã㯠Firebase ã»ãã·ã§ã³ãçµäºããŸããsignOut
ïŒãã®ã¡ãœããã¯çŸåšãµã€ã³ã€ã³ãããŠãŒã¶ãŒã®ãããã¡ã€ã«æ å ±ã§ãã©ã¡ãŒã¿ãååŸããããã䜿ã£ãŠãŠãŒã¶ãŒã® Firebase ãããã¡ã€ã«ãæŽæ°ããŸããupdateProfile
ïŒãã®ã¡ããœãã¯çŸåšã®ãŠãŒã¶ãŒã®è©³çŽ°ãè¿ããŸããgetCurrentUser
泚ïŒ
ãYOUR_PROJECT_APIKEY
ãããã³ÂYOUR_PROJECT_AUTHDOMAIN
 ãç¬èªã® Firebase å€ãšçœ®ãæããŸããããããã¬ãŒã¹ãã«ããŒã¯ããããåã«ã³ããŒããÂYOUR_PROJECT_ID
ãapiKey
ãããã³authDomain
 å€ãšçœ®ãæããããšãã§ããŸããprojectId
ããã§ããã®ã¹ã¯ãªãããå®äºããã«ã¯ã次ã®ã¡ãœãããÂ
Firebase
 ã¯ã©ã¹ã«è¿œå ããŸããlet _messagesDb = null; class Firebase { // ... constructor and methods defined above ... setAuthStateListener(listener) { firebase.auth().onAuthStateChanged(listener); } setMessagesListener(listener) { _messagesDb.collection('messages').orderBy('createdAt', 'desc').limit(10).onSnapshot(listener); } async setToken(token) { await firebase.auth().signInWithCustomToken(token); } } const firebaseClient = new Firebase();
æ³šïŒ æåŸã®ã©ã€ã³ãå ãå¿ããªãã§ãã ããïŒ
ïŒãconst firebaseClient = new Firebase();
ãããæ°ããã¡ãœããã¯æ¬¡ã®æ©èœããã®ã¯ã©ã¹ã«è¿œå ããŸãã
ïŒãã®ã¡ãœããã¯ã Firebase ã®èªèšŒç¶æ ãå€ãããšãã¯ãã€ã§ãåŒã³åºããªã¹ããŒãè¿œå ããã¢ããªãæå¹ã«ããŸããsetAuthListener
ïŒãã®ã¡ãœãã㯠Firestore ããŒã¿ããŒã¹ã®ÂsetMessagesListener
ã³ã¬ã¯ã·ã§ã³ã«ãªã¹ããŒãè¿œå ããŸããFirebase ã¯ãã®ã³ã¬ã¯ã·ã§ã³ãå€ãããšãã€ã§ããªã¢ã«ã¿ã€ã ã§ãã®ãªã¹ããŒãåŒã³åºããŸããmessages
ïŒãã®ã¡ãœããã¯ãµãŒããŒã«çæããã«ã¹ã¿ã ããŒã¯ã³ãåãåãããããã Firebase ã§èªèšŒããããã«äœ¿çšããŸããsetToken
ã¢ããªã Firebase ã§éä¿¡ããããã«å¿ èŠãªæ©èœã¯ããã ãã§ãã次ã«ãAuth0 ããã³ Firebase ã®äž¡æ¹ãäžç·ã«çµ±åããŠãªã¢ã«ã¿ã€ã Web ãã£ãããæ§ç¯ããããã«ãã¯ã©ã€ã¢ã³ãåŽã¢ããªã®äž»ã¹ã¯ãªãããäœããŸãã
ãªã¢ã«ã¿ã€ã Web ãã£ãã UI ãå®è£ ãã
ãªã¢ã«ã¿ã€ã ãã£ãã ã¢ããªãå®æããããã«æåŸã«å¿ èŠãªããšã¯Â
index.js
 ãšããæ°ãããã¡ã€ã«ã ./src/public/app
 ã«äœãã次ã®ã³ãŒããããã«æ¿å
¥ããŸãã// ./src/public/app/index.js const chatArea = document.getElementById('chat-area'); const messageInput = document.getElementById('message'); const profileElement = document.getElementById('profile'); const signInButton = document.getElementById('sign-in'); const signOutButton = document.getElementById('sign-out'); messageInput.addEventListener('keyup', async (event) => { if (event.code !== 'Enter') return; firebaseClient.addMessage(messageInput.value); messageInput.value = ''; }); signInButton.addEventListener('click', async () => { auth0Client.signIn(); }); signOutButton.addEventListener('click', async () => { auth0Client.signOut(); firebaseClient.signOut(); deactivateChat(); }); async function setFirebaseCustomToken() { const response = await fetch('http://localhost:3001/firebase', { headers: { 'Authorization': `Bearer ${auth0Client.getIdToken()}`, }, }); const data = await response.json(); await firebaseClient.setToken(data.firebaseToken); await firebaseClient.updateProfile(auth0Client.getProfile()); activateChat(); } function activateChat() { const {displayName} = firebase.auth().currentUser; profileElement.innerText = `Hello, ${displayName}.`; signInButton.style.display = 'none'; signOutButton.style.display = 'inline-block'; messageInput.disabled = false; firebaseClient.setMessagesListener((querySnapshot) => { chatArea.innerHTML = ''; querySnapshot.forEach((doc) => { const messageContainer = document.createElement('div'); const timestampElement = document.createElement('small'); const messageElement = document.createElement('p'); const messageDate = new Date(doc.data().createdAt.seconds * 1000); timestampElement.innerText = doc.data().author + ' - ' + messageDate.toISOString().replace('T', ' ').substring(0, 19); messageElement.innerText = doc.data().message; messageContainer.appendChild(timestampElement); messageContainer.appendChild(messageElement); messageContainer.className = 'alert alert-secondary'; chatArea.appendChild(messageContainer); }); }); } function deactivateChat() { profileElement.innerText = ''; signInButton.style.display = 'inline-block'; signOutButton.style.display = 'none'; messageInput.disabled = true; } (async () => { deactivateChat(); const loggedInThroughCallback = await auth0Client.handleCallback(); if (loggedInThroughCallback) await setFirebaseCustomToken(); })();
ãããžã§ã¯ãã«è¿œå ããæ°ããã¹ã¯ãªããã®äž»ãªç®æšã¯ UI ã¢ããªå šäœãã³ã³ãããŒã«ããã«ã¹ã¿ã ããŒã¯ã³ã§ Firebase ã«ãµã€ã³ã€ã³ããããšã§ããããã«å ·äœçã«ã¯ããã®ã¹ã¯ãªããã¯æ¬¡ã® UI èŠçŽ ã«åç §ãäœã£ãŠå§ããŸãã
ïŒã¢ããªãã¡ãã»ãŒãžã衚瀺ããå ŽåchatArea
ïŒãŠãŒã¶ãŒãã¡ãã»ãŒãžãã¿ã€ãããå ŽåmessageInput
ïŒã¢ããªããã°ã€ã³ãããŠãŒã¶ãŒã®ååã衚瀺ããå ŽåprofileElement
ïŒããã§ãŠãŒã¶ãŒã®èªèšŒãå¯èœã«ããŸããsignInButton
ïŒããã§ãŠãŒã¶ãŒã®ãµã€ã³ã¢ãŠããå¯èœã«ããŸããsignOutButton
ãã®åŸãã¹ã¯ãªããã¯Â
keyUp
 ãªã¹ããŒã messageInput
 èŠçŽ ã«è¿œå ããŸãããã®ãªã¹ããŒã¯ãŠãŒã¶ãŒãæŒãããŒã確èªããEnter
 ããŒãæŒããŠããã°ããã®ãªã¹ããŒã¯æ°ããã¡ãã»ãŒãžãçºè¡ããããã«Â firebaseClient.addMessage
 ãåŒã³åºããŸããã¹ã¯ãªããã次ã«ããããšã¯ãã€ãã³ã ãªã¹ããŒãÂ
signInButton
ãšÂ signOutButton
 ã«è¿œå ããŠãŠãŒã¶ãŒãèªèšŒããŠå¿
èŠãªæã«ãµã€ã³ã¢ãŠãã§ããããã«ããŸãã次ã«ã
setFirebaseCustomToken
 ãšããé¢æ°ãå®çŸ©ããåŒã³åºããããšãã«ãAuth0 ããååŸãã idToken
 ã䜿ã£ãŠ AJAX ãªã¯ãšã¹ãã http://localhost:3001/firebase
 ã«çºè¡ããŸããããã§ã®ç®æšã¯ããã¯ãšã³ã ãµãŒããŒããã«ã¹ã¿ã Firebase ããŒã¯ã³ãååŸããããšã§ãã¢ããªãåé¡ãªã Firestore ããŒã¿ããŒã¹ãšïŒèªèšŒã®ããã«ïŒéä¿¡ã§ããããã«ããããšã§ãããŸãããã®é¢æ°ã¯ Auth0 ãè¿ãããããã¡ã€ã«ã§çŸåšã®ãŠãŒã¶ãŒã® Firebase ãããã¡ã€ã«ãæŽæ°ããŸãããããã§ããã®ã§ããã®ã¹ã¯ãªããã¯ããã«2ã€ã®é¢æ°ãè¿œå ããŸãã
ïŒãã®é¢æ°ã¯ UI å šäœãã¢ã¯ãã£ãã«ããŠçŸåšã®ãŠãŒã¶ãŒãã¡ãã»ãŒãžãçºè¡ã§ããããã«ãããªã¹ããŒã Firestore ã«å ããŠæ°ããã¡ãã»ãŒãžãå°çãããšãã«ãUI ãæŽæ°ãããŸããactivateChat
ïŒãã®é¢æ°ã¯ãŠãŒã¶ãŒããµã€ã³ã¢ãŠãããããã£ãããã¯ãªã¢ã«ããŸããdeactivateChat
ãããããæåŸã«ãã®ã¹ã¯ãªãããããããšã¯ã次ã®2ã€ãããããã«Â IIFEïŒå³æå®è¡é¢æ°åŒïŒã䜿çšããããšã§ãã
- ãŠãŒã¶ãŒã Auth0 ããæ»ããã©ããã確èªããããã«Â
 é¢æ°ãåŒã³åºããŸãïŒèªèšŒåŸïŒãhandleCallback
- ïŒãŠãŒã¶ãŒããµã€ã³ã€ã³ãããïŒã«ã¹ã¿ã ããŒã¯ã³ã§ Firebase ã«ãµã€ã³ã€ã³ããããã«
é¢æ°ãåŒã³åºããŸããsetFirebaseCustomToken
âãªã¢ã«ã¿ã€ã Web ã¢ããªã Firebase ã§äœãããšã¯ç°¡åã§æ¥œããã§ããâ
ããããã€ãŒããã
ãªã¢ã«ã¿ã€ã Web ãã£ããããã¹ããã
ãããŸããïŒãªã¢ã«ã¿ã€ã Web ãã£ããã®äœæãçµãããŸãããã§ã¯ãããã䜿ã£ãŠã¿ãŸããããã¢ããªãå®è¡ããã«ã¯ããããžã§ã¯ã ã«ãŒã ãã£ã¬ã¯ããªã«ããããšã確èªãã次ã®ã³ãã³ããçºè¡ããŸãã
# server.js ã§äœ¿çšãã env å€æ°ãå®çŸ©ããŸã export AUTH0_DOMAIN=YOUR_APP_DOMAIN export AUTH0_API_AUDIENCE=YOUR_APP_AUDIENCE # ã¢ããªãå®è¡ããŸã node src/server
泚ïŒ
 ãç¬èªã® Auth0 ãã¡ã€ã³ã«ãÂYOUR_APP_DOMAIN
 ã Auth0 ã¢ããªã±ãŒã·ã§ã³ ã¯ã©ã€ã¢ã³ã id ã«çœ®ãæããå¿ èŠããããŸãããããäž¡æ¹ã®å€ã¯ä»¥åã«å®çŸ©ããÂAUTH0_API_AUDIENCE
 ãã¡ã€ã«ã«ãããŸãïŒåauth0.js
ããã³Âdomain
ïŒãclientID
ãã®åŸã
 ã Web ãã©ãŠã¶ãŒã«éããšãã¹ã¯ãªãŒã³ã« Web ãã£ããã衚瀺ãããŸããããããããµã€ã³ã€ã³ãã¯ãªãã¯ãããšãã¢ããªã Auth0 ã«ãªãã€ã¬ã¯ããããŠèªèšŒããŠãã£ãããå§ããããšãã§ããŸãããµã€ã³ã€ã³ããããAuth0 ã¯ã¢ããªã«ãªãã€ã¬ã¯ãããã¡ãã»ãŒãžãéãå§ããããšãã§ããŸãïŒã¡ãã»ãŒãžãã¿ã€ãã㊠Enter ããŒãæŒãã ãïŒãçŽ æŽãããã§ããïŒhttp://localhost:3001
ãŸãšã
æ¬æžã§ã¯ Firebase ããã³ Firestore ã䜿ã£ãŠãªã¢ã«ã¿ã€ã Web ã¢ããªãæ§ç¯ããæ¹æ³ãåŠã³ãŸããããã®ã»ãã«ãã«ã¹ã¿ã èªèšŒã·ã¹ãã ãšã㊠Auth0 ã Firebase ã€ã³ã¹ã¿ã³ã¹ã«æ§æããæ¹æ³ãšãã®çç±ã«ã€ããŠãåŠã³ãŸãããæåŸã«ãFirebase ããã³ Auth0 ã®äž¡æ¹ã䜿ãçŽ æµãªãèªåã® Web ãã£ããã¢ããªã±ãŒã·ã§ã³ãäœããã¢ãã³ã§ãªã¢ã«ã¿ã€ã ã® Web ã¢ããªãã§ããŸãããçŽ æŽãããã§ãããïŒ
About the author
Obielum Godson
Full-Stack Developer