ããã³ããšã³ããšããžé¢æ°ã掻çšãã匷åãªå°ççã«ãŒãã£ã³ã°ã®æ¹æ³ã解説ããŸãããã®å æ¬çãªã¬ã€ãã§ã¯ãããã©ãŒãã³ã¹åäžãããŒã¿ã³ã³ãã©ã€ã¢ã³ã¹ãã°ããŒãã«èŠæš¡ã§ã®ã³ã³ãã³ãããŒã«ã©ã€ãŒãŒã·ã§ã³ãå®çŸãããã±ãŒã·ã§ã³ããŒã¹ã®ãªã¯ãšã¹ãé ä¿¡ãã«ããŒããŸãã
ããã³ããšã³ããšããžé¢æ°ã«ããå°ççã«ãŒãã£ã³ã°ïŒãã±ãŒã·ã§ã³ããŒã¹ã®ãªã¯ãšã¹ãé ä¿¡ã¬ã€ã
仿¥ã®çžäºæ¥ç¶ãããäžçã«ãããŠãã°ããŒãã«ãªèŠèŽè ã察象ãšããã¢ããªã±ãŒã·ã§ã³ã®æ§ç¯ã¯ãã¯ãéžæè¢ã§ã¯ãªããå¿ é äºé ã§ããããããã°ããŒãã«ãªãŠãŒã¶ãŒããŒã¹ã¯ç¹æã®èª²é¡ãæç€ºããŸããæ±äº¬ã®ãŠãŒã¶ãŒãšãã«ãªã³ã®ãŠãŒã¶ãŒã«æå°éã®é å»¶ã§ã³ã³ãã³ããé ä¿¡ããã«ã¯ã©ãããã°ããã§ããããïŒãšãŒãããã®GDPRã®ãããªå°åããŒã¿ãã©ã€ãã·ãŒæ³ã«æºæ ããã«ã¯ã©ãããã°ããã§ããããïŒåãŠãŒã¶ãŒã«ãšã£ãŠãã€ãã£ãã«æããããé貚ãèšèªãªã©ã®ããŒã«ã©ã€ãºãããã³ã³ãã³ããæç€ºããã«ã¯ã©ãããã°ããã§ããããïŒãã®çãã¯ããããã¯ãŒã¯ã®ãšããžã«ãããŸãã
ããã³ããšã³ããšããžé¢æ°ã«ããå°ççã«ãŒãã£ã³ã°ã®äžçãžããããããã®åŒ·åãªãã©ãã€ã ã¯ããšããžé¢æ°ã®äœé å»¶å®è¡ãšãã±ãŒã·ã§ã³ããŒã¹ã®ããžãã¯ã®ã€ã³ããªãžã§ã³ã¹ãçµã¿åãããããé«éã§ãã³ã³ãã©ã€ã¢ã³ã¹ã«æºæ ããé«åºŠã«ããŒãœãã©ã€ãºããããŠãŒã¶ãŒäœéšãåµåºããŸãããªã¯ãšã¹ãããããã¯ãŒã¯ãšããžïŒãŠãŒã¶ãŒã«ç©ççã«è¿ãå ŽæïŒã§ææããããšã«ãããéçºè ã¯ãªã¯ãšã¹ããäžå€®éæš©åã®ãªãªãžã³ãµãŒããŒã«å°éããåã«åçãªã«ãŒãã£ã³ã°æ±ºå®ãäžãããšãã§ããŸãã
ãã®å æ¬çãªã¬ã€ãã§ã¯ããšããžã§ã®å°ççã«ãŒãã£ã³ã°ã«ã€ããŠç¥ãã¹ããã¹ãŠã解説ããŸãããããäœã§ãããããªãçŸä»£ã®ãŠã§ãéçºã«ãšã£ãŠç»æçãªã®ãããããŠã©ã®ããã«å®è£ ã§ããããæ¢ããŸããã°ããŒãã«ã·ã¹ãã ãèšèšããã¢ãŒããã¯ããããã©ãŒãã³ã¹ãæé©åããéçºè ããŸãã¯ããè¯ãããŒãœãã©ã€ãŒãŒã·ã§ã³ãç®æããããã¯ããããŒãžã£ãŒã§ãã£ãŠãããã®èšäºã¯ãã±ãŒã·ã§ã³ããŒã¹ã®ãªã¯ãšã¹ãé ä¿¡ããã¹ã¿ãŒããããã®æŽå¯ãšå®è·µçãªç¥èãæäŸããŸãã
å°ççã«ãŒãã£ã³ã°ãšã¯ïŒ
ãã®æ žå¿ã«ãããŠãå°ççã«ãŒãã£ã³ã°ïŒãŸãã¯ãžãªã«ãŒãã£ã³ã°ïŒãšã¯ããªã¯ãšã¹ãå ã®ãŠãŒã¶ãŒã®å°ççãªå Žæã«åºã¥ããŠããããã¯ãŒã¯ãã©ãã£ãã¯ãç°ãªãå®å ã«èªå°ããææ³ã§ããããã¯ã€ã³ã¿ãŒãããã®ããã®ã¹ããŒããªäº€é管å¶å®ã®ãããªãã®ã§ãåãŠãŒã¶ãŒã®ãªã¯ãšã¹ãããããæºããã®ã«æãé©åãªãµãŒããŒããµãŒãã¹ã«éä¿¡ãããããšãä¿èšŒããŸãã
åŸæ¥ã®ã¢ãããŒã vs. ãšããžé©åœ
æŽå²çã«ããžãªã«ãŒãã£ã³ã°ã¯äž»ã«DNSã¬ãã«ã§åŠçãããŠããŸãããGeoDNSãšåŒã°ããæè¡ã¯ãDNSã¯ãšãªã®çºä¿¡å ã«å¿ããŠãã¡ã€ã³åãç°ãªãIPã¢ãã¬ã¹ã«è§£æ±ºããŸãããäŸãã°ãã¢ãžã¢ã®ãŠãŒã¶ãŒã¯ã·ã³ã¬ããŒã«ã®ãµãŒããŒã®IPã¢ãã¬ã¹ãååŸãããšãŒãããã®ãŠãŒã¶ãŒã¯ãã©ã³ã¯ãã«ãã®ãµãŒããŒã«èªå°ãããŸããã
ç°ãªãå°åã®ããŒã¿ã»ã³ã¿ãŒã«ãã©ãã£ãã¯ãèªå°ããã®ã«å¹æçã§ããäžæ¹ã§ãDNSããŒã¹ã®ã«ãŒãã£ã³ã°ã«ã¯éçããããŸãïŒ
- ç²åºŠã®æ¬ åŠïŒDNSã¯é«ã¬ãã«ã§åäœããŸããåã ã®ãªã¯ãšã¹ãããããŒãæ€æ»ããããDNSã¯ãšãªã®çºä¿¡å 以å€ã®æ å ±ã«åºã¥ããŠæ±ºå®ãäžãããšã¯ã§ããŸããã
- ãã£ãã·ã¥ã®é å»¶ïŒDNSã¬ã³ãŒãã¯ã€ã³ã¿ãŒãããå šäœã§åŒ·åã«ãã£ãã·ã¥ãããŸãã倿Žãã°ããŒãã«ã«äŒæããã®ã«æ°åããæ°æéãããããšããããåçã§ãªã¢ã«ã¿ã€ã ãªã«ãŒãã£ã³ã°ã«ã¯äžåãã§ãã
- äžæ£ç¢ºãïŒå Žæã¯ãŠãŒã¶ãŒã®DNSãªãŸã«ãã«åºã¥ããŠãããããããŠãŒã¶ãŒã®å®éã®å Žæãæ£ç¢ºã«åæ ããŠããªãå ŽåããããŸãïŒäŸïŒGoogleã®8.8.8.8ã®ãããªãããªãã¯DNSã䜿çšããŠããå ŽåïŒã
ãšããžé¢æ°ã¯ãã®ããã»ã¹ã«é©åœããããããŸããDNSã¬ãã«ã§ã«ãŒãã£ã³ã°ãã代ããã«ãããžãã¯ã¯ã³ã³ãã³ãããªããªãŒãããã¯ãŒã¯ïŒCDNïŒã®Point of PresenceïŒPoPïŒã§ããã¹ãŠã®HTTPãªã¯ãšã¹ãã«å¯ŸããŠå®è¡ãããŸããããã«ããããããã€ããŒããæäŸãããæ£ç¢ºãªäœçœ®ããŒã¿ã«åºã¥ããããªã¢ã«ã¿ã€ã ã®ããªã¯ãšã¹ãããšã®æ±ºå®ãå¯èœã«ãªããã¯ããã«åŒ·åã§æè»ãªã¢ãããŒããæäŸãããŸãã
ãšããžã®åïŒãªããšããžé¢æ°ãå®ç§ãªããŒã«ãªã®ã
ãšããžé¢æ°ããªãããã»ã©å¹æçãªã®ããçè§£ããããã«ã¯ããŸãããšããžããçè§£ããå¿ èŠããããŸãããšããžãšã¯ãäžçäžã®ããŒã¿ã»ã³ã¿ãŒã«æŠç¥çã«é 眮ããããµãŒããŒã®ã°ããŒãã«ãããã¯ãŒã¯ã§ãããŠãŒã¶ãŒãããªãã®ãµã€ãã蚪ãããšã圌ãã®ãªã¯ãšã¹ãã¯é ãé¢ããäžå€®éæš©åã®ãµãŒããŒã§ã¯ãªããç©ççã«æãè¿ããµãŒããŒã«ãã£ãŠåŠçãããŸãã
ãšããžé¢æ°ã¯ããã®ãããã¯ãŒã¯äžã§å®è¡ãããå°ããªãµãŒããŒã¬ã¹ã®ã³ãŒãçïŒå€ãã¯JavaScript/TypeScriptïŒã§ããå°ççã«ãŒãã£ã³ã°ã«çæ³çãªããŒã«ã§ããçç±ã¯æ¬¡ã®ãšããã§ãïŒ
1. è¶ äœé å»¶
ç©çæ³åã¯ããŠã§ãããã©ãŒãã³ã¹ã«ããã究極ã®ããã«ããã¯ã§ããããŒã¿ã倧éžã暪æããã®ã«ãããæéã¯éèŠã§ããã«ãŒãã£ã³ã°ããžãã¯ãæå¯ãã®ãšããžããŒãã§å®è¡ããããšã§ã決å®ã¯ããªç§åäœã§è¡ãããŸããããã«ããããªãªãžã³ãµãŒããŒãžã®åŸåŸ©ã®ããã«ãã£ãªãã«ãã»ãŒç¬æã«ãŠãŒã¶ãŒããªãã€ã¬ã¯ããããããªã¯ãšã¹ãããªãŒãžã§ãã«ããã¯ãšã³ãã«æžãæããããããŒã«ã©ã€ãºãããã³ã³ãã³ããæäŸãããããããšãã§ããŸãã
2. ç²åºŠã®çްããããªã¯ãšã¹ãããšã®å¶åŸ¡
DNSãšã¯ç°ãªãããšããžé¢æ°ã¯åä¿¡ããHTTPãªã¯ãšã¹ãå šäœãæ€æ»ã§ããŸããããã«ã¯ããããŒãã¯ãããŒãã¯ãšãªãã©ã¡ãŒã¿ãªã©ãå«ãŸããŸããææ°ã®ãšããžãã©ãããã©ãŒã ã¯ããŠãŒã¶ãŒã®åœãå°åãéœåžãªã©ã®ä¿¡é Œæ§ã®é«ãå°çããŒã¿ããªã¯ãšã¹ãã«æ¿å ¥ããŸããããã«ãããç¹å®ã®éœåžã®ãŠãŒã¶ãŒãããŒã¿æ©èœã«ã«ãŒãã£ã³ã°ããããå¶è£å¯Ÿè±¡å°åããã®ãã©ãã£ãã¯ããããã¯ããããããªã©ãéåžžã«ãã现ããã«ãŒã«ãå¯èœã«ãªããŸãã
3. ãªãªãžã³ã®è² è·ãšã³ã¹ãã®åæž
ã«ãŒãã£ã³ã°ããžãã¯ããšããžã§åŠçããããšã§ããã©ã€ããªã¢ããªã±ãŒã·ã§ã³ãµãŒããŒããããªãã®äœæ¥ããªãããŒãã§ããŸãããªã¯ãšã¹ãããšããžãã£ãã·ã¥ããçŽæ¥æäŸããããããªãã€ã¬ã¯ãããããããšããžã§ãããã¯ããããããå Žåãé«äŸ¡ãªãªãªãžã³ã®ã³ã³ãã¥ãŒãã£ã³ã°ãªãœãŒã¹ãæ¶è²»ããå¿ èŠããããŸãããããã«ãããããå埩åããããã¹ã±ãŒã©ãã«ã§ãã³ã¹ãå¹çã®é«ãã¢ãŒããã¯ãã£ãå®çŸããŸãã
4. ææ°ãã¬ãŒã ã¯ãŒã¯ãšã®ã·ãŒã ã¬ã¹ãªçµ±å
VercelãNetlifyãCloudflareãªã©ã®ãã©ãããã©ãŒã ã¯ããšããžé¢æ°ãéçºã¯ãŒã¯ãããŒã«å¯æ¥ã«çµ±åããŠããŸããNext.jsãNuxtãSvelteKitã®ãããªãã¬ãŒã ã¯ãŒã¯ã䜿çšãããšããšããžããžãã¯ã®å®è£ ã¯ãããžã§ã¯ãã«`middleware.ts`ãã¡ã€ã«ã远å ããã®ãšåããããç°¡åã«ãªããæ·±ãDevOpsã®å°éç¥èããªããŠãããã³ããšã³ãéçºè ãã¢ã¯ã»ã¹ã§ããããã«ãªããŸãã
ãšããžé¢æ°ã«ããå°ççã«ãŒãã£ã³ã°ã®ä»çµã¿ïŒã¹ããããã€ã¹ãããã®è§£èª¬
ãšããžããŒã¹ã®å°ççã«ãŒãã£ã³ã°ã®ä»çµã¿ãçè§£ããããã«ããŠãŒã¶ãŒãªã¯ãšã¹ãã®éã®ãããã©ã£ãŠã¿ãŸãããã
- ãŠãŒã¶ãŒããªã¯ãšã¹ããéå§ïŒè±åœãã³ãã³ã®ãŠãŒã¶ãŒããã©ãŠã¶ã«ãŠã§ããµã€ãã®URLãå ¥åããŸãã
- ãªã¯ãšã¹ããæå¯ãã®ãšããžããŒãã«å°éïŒãªã¯ãšã¹ãã¯ç±³åœã®ãµãŒããŒãŸã§ãã£ãšç§»åããããã§ã¯ãããŸããã代ããã«ãæå¯ãã®Point of PresenceïŒPoPïŒããããããã³ãã³ã§ææãããŸãã
- ãšããžé¢æ°ãåŒã³åºãããïŒãšããžãã©ãããã©ãŒã ã¯ããã®ãã¹ã«ãšããžé¢æ°ãèšå®ãããŠããããšãæ€åºããŸãã颿°ã®ã³ãŒãã¯å³åº§ã«å®è¡ãããŸãã
- äœçœ®ããŒã¿ã«ã¢ã¯ã»ã¹ïŒãã©ãããã©ãŒã ã¯ãç¹å¥ãªãªã¯ãšã¹ãããããŒïŒäŸïŒ`x-vercel-ip-country: 'GB'`ã`cf-ipcountry: 'GB'`ïŒãŸãã¯`request.geo`ãªããžã§ã¯ããä»ããŠããŠãŒã¶ãŒã®äœçœ®ããŒã¿ã颿°ã«èªåçã«æäŸããŸãã
- ã«ãŒãã£ã³ã°ããžãã¯ãé©çšãããïŒã³ãŒããããžãã¯ãå®è¡ããŸããåœã³ãŒãã確èªããŸããäŸïŒ
if (country === 'GB') { ... }
- ã¢ã¯ã·ã§ã³ãå®è¡ãããïŒããžãã¯ã«åºã¥ããŠã颿°ã¯ããã€ãã®ã¢ã¯ã·ã§ã³ãå®è¡ã§ããŸãïŒ
- ãªãŒãžã§ãã«ããã¯ãšã³ããžã®ãªã©ã€ãïŒé¢æ°ã¯ããŠãŒã¶ãŒã®ãã©ãŠã¶ã®URLã倿Žããã«ããªã¯ãšã¹ãã`https://api.eu.your-service.com`ã®ãããªå¥ã®ãµãŒããŒã«éãã«è»¢éã§ããŸããããã¯ããŒã¿ã¬ãžãã³ã·ãŒã®ã³ã³ãã©ã€ã¢ã³ã¹ã«æé©ã§ãã
- ããŒã«ã©ã€ãºãããURLãžã®ãªãã€ã¬ã¯ãïŒé¢æ°ã¯307ïŒäžæçãªãã€ã¬ã¯ãïŒãŸãã¯308ïŒæä¹ çãªãã€ã¬ã¯ãïŒã¬ã¹ãã³ã¹ãè¿ãããŠãŒã¶ãŒã`https://your-site.co.uk`ã®ãããªãµã€ãã®ããŒã«ã©ã€ãºçã«éä¿¡ã§ããŸãã
- ã¬ã¹ãã³ã¹ã®å€æŽïŒé¢æ°ã¯ãªãªãžã³ããå ã®ã³ã³ãã³ããååŸããããããŠãŒã¶ãŒã«éä¿¡ããåã«ãããŒã«ã©ã€ãºãããã³ã³ãã³ããäŸ¡æ ŒããŸãã¯èšèªæååãåçã«æ¿å ¥ããŠå€æŽã§ããŸãã
- ãªã¯ãšã¹ãã®ãããã¯ïŒãŠãŒã¶ãŒãå¶éãããå°åããã®å Žåã颿°ã¯403ïŒForbiddenïŒã¬ã¹ãã³ã¹ãè¿ããã¢ã¯ã»ã¹ãå®å šã«é²ãããšãã§ããŸãã
- ãã£ãã·ã¥ããã®æäŸïŒããŒãžã®ããŒã«ã©ã€ãºçããã§ã«ãšããžãã£ãã·ã¥ã«ããå ŽåããããçŽæ¥æäŸããŠãå¯èœãªéãæéã®ã¬ã¹ãã³ã¹ãæäŸã§ããŸãã
ãã®å šããã»ã¹ã¯ãŠãŒã¶ãŒã«ã¯ééçã«ããããŠã»ãã®äžç¬ã§è¡ãããã·ãŒã ã¬ã¹ã§æé©åãããäœéšãããããããŸãã
å®è·µçãªãŠãŒã¹ã±ãŒã¹ãšåœéçãªäŸ
å°ççã«ãŒãã£ã³ã°ã®çã®åã¯ããã®å®éã®ã¢ããªã±ãŒã·ã§ã³ã§æããã«ãªããŸããã°ããŒãã«ããžãã¹ã«ãšã£ãŠæãäžè¬çã§åœ±é¿åã®ãããŠãŒã¹ã±ãŒã¹ãããã€ãæ¢ã£ãŠã¿ãŸãããã
ã±ãŒã¹ã¹ã¿ãã£1ïŒEã³ããŒã¹ã®ããŒã«ã©ã€ãŒãŒã·ã§ã³
課é¡ïŒã°ããŒãã«ãªãªã³ã©ã€ã³å°å£²æ¥è ããããŒã«ã©ã€ãºãããã·ã§ããã³ã°äœéšãæäŸããããšèããŠããŸããããã«ã¯ãçŸå°é貚ã§ã®äŸ¡æ Œè¡šç€ºãé¢é£ååã®è¡šç€ºãæ£ããèšèªã®äœ¿çšãå«ãŸããŸãã
ãšããžãœãªã¥ãŒã·ã§ã³ïŒ
- ãšããžé¢æ°ãåä¿¡ãªã¯ãšã¹ãã®`geo.country`ããããã£ãæ€æ»ããŸãã
- åœã'JP'ïŒæ¥æ¬ïŒã®å ŽåããŠãŒã¶ãŒã`mystore.com`ãã`mystore.com/jp`ã«ãªãã€ã¬ã¯ãããŸãã
- `/jp`ããŒãžã¯ãäŸ¡æ ŒãJPYïŒåïŒã§ãã³ã³ãã³ããæ¥æ¬èªã§ãµãŒããŒã¬ã³ããªã³ã°ããŸãã
- åœã'DE'ïŒãã€ãïŒã®å Žåã颿°ã¯ãªã¯ãšã¹ããããšãŒãããã®åšåº«ããŒã¿ããŒã¹ããååããŒã¿ãååŸããäŸ¡æ ŒãEURïŒâ¬ïŒã§è¡šç€ºããããŒãžã®ããŒãžã§ã³ã«ãªã©ã€ãããŸããããã¯ç®ã«èŠããURLã®å€æŽãªãã«è¡ãããã¹ã ãŒãºãªäœéšãæäŸããŸãã
ã±ãŒã¹ã¹ã¿ãã£2ïŒããŒã¿äž»æš©ãšGDPRã³ã³ãã©ã€ã¢ã³ã¹
課é¡ïŒããSaaSäŒæ¥ã¯ã°ããŒãã«ã«ãµãŒãã¹ãæäŸããŠããŸãããEUåžæ°ã®ããŒã¿ã®ä¿åã»åŠçå Žæã«é¢ãã峿 ŒãªèŠåãæã€EUã®äžè¬ããŒã¿ä¿è·èŠåïŒGDPRïŒã«æºæ ããå¿ èŠããããŸãã
ãšããžãœãªã¥ãŒã·ã§ã³ïŒ
- ãšããžé¢æ°ããã¹ãŠã®APIãªã¯ãšã¹ãã®`geo.country`ã確èªããŸãã
- EU諞åœã®ãªã¹ããç¶æãããŸãïŒ`['FR', 'DE', 'ES', 'IE', ...]`ã
- ãŠãŒã¶ãŒã®åœãEUãªã¹ãã«ããå Žåã颿°ã¯å éšçã«ãªã¯ãšã¹ãURLã`api.mysaas.com`ãã`api.eu.mysaas.com`ã«ãªã©ã€ãããŸãã
- `api.eu.mysaas.com`ãšã³ããã€ã³ãã¯ã欧å·é£åå ã«ç©ççã«èšçœ®ããããµãŒããŒïŒäŸïŒãã©ã³ã¯ãã«ãããããªã³ïŒã§ãã¹ããããŸãã
- ä»ã®ãã¹ãŠã®å°åïŒäŸïŒ'US'ã'CA'ã'AU'ïŒããã®ãªã¯ãšã¹ãã¯ãç±³åœã§ãã¹ããããŠããæ±çšããã¯ãšã³ãã«ã«ãŒãã£ã³ã°ãããŸãã
ã±ãŒã¹ã¹ã¿ãã£3ïŒãªã³ã©ã€ã³ã²ãŒã ã®ããã©ãŒãã³ã¹æé©å
課é¡ïŒãã«ããã¬ã€ã€ãŒãªã³ã©ã€ã³ã²ãŒã ã®éçºè ã¯ãå ¬æ£ã§å¿çæ§ã®é«ãã²ãŒã ãã¬ã€ãä¿èšŒããããã«ãå¯èœãªéãäœãã¬ã€ãã³ã·ãŒïŒpingïŒã§ãã¬ã€ã€ãŒãã²ãŒã ãµãŒããŒã«æ¥ç¶ããå¿ èŠããããŸãã
ãšããžãœãªã¥ãŒã·ã§ã³ïŒ
- ã²ãŒã ã¯ã©ã€ã¢ã³ããèµ·åãããšãã°ããŒãã«APIãšã³ããã€ã³ãã«ããããã¡ã€ãã³ã°ããªã¯ãšã¹ããéä¿¡ããŸãã
- ãšããžé¢æ°ããã®ãªã¯ãšã¹ããææããŸãããŠãŒã¶ãŒã®å ŽæïŒ`geo.country`ãš`geo.region`ïŒãç¹å®ããŸãã
- 颿°ã¯ãå°ççå°åãšæå¯ãã®ã²ãŒã ãµãŒããŒã®IPã¢ãã¬ã¹ã®ãããã³ã°ãç¶æããŸãïŒ`{'us-east': '1.2.3.4', 'eu-west': '5.6.7.8', 'ap-southeast': '9.10.11.12'}`ã
- 颿°ã¯ãæé©ãªã²ãŒã ãµãŒããŒã®IPã¢ãã¬ã¹ãå«ãAPIãªã¯ãšã¹ããžã®å¿çãè¿ããŸãã
- ã²ãŒã ã¯ã©ã€ã¢ã³ãã¯ãã®åŸããã®ãµãŒããŒã«çŽæ¥æ¥ç¶ããŸãã
ã±ãŒã¹ã¹ã¿ãã£4ïŒæ®µéçãªããŒã«ã¢ãŠããšA/Bãã¹ã
課é¡ïŒãããã¯ãããžãŒäŒæ¥ãå€§èŠæš¡ãªæ°æ©èœãããŒã³ãããããããªã¹ã¯ã軜æžããããã«ã°ããŒãã«ãªãªãŒã¹åã«å°èŠæš¡ãªãªãŒãã£ãšã³ã¹ã§ãã¹ãããããšèããŠããŸãã
ãšããžãœãªã¥ãŒã·ã§ã³ïŒ
- æ°æ©èœã¯ãã£ãŒãã£ãŒãã©ã°ã®èåŸã«ãããã€ãããŸãã
- ãšããžé¢æ°ã¯ã¯ãããŒïŒãŠãŒã¶ãŒããªããã€ã³ãããã©ããã確èªããããïŒãšãŠãŒã¶ãŒã®å Žæã®äž¡æ¹ããã§ãã¯ããŸãã
- ããžãã¯ã¯ããã¥ãŒãžãŒã©ã³ãïŒ'NZ'ïŒã®ãããªç¹å®ã®äœãªã¹ã¯åžå Žã®ãã¹ãŠã®ãŠãŒã¶ãŒã«å¯ŸããŠæ©èœãæå¹ã«ããããã«èšå®ãããŸãã`if (geo.country === 'NZ') { enableFeature(); }`
- ãã¥ãŒãžãŒã©ã³ã以å€ã®ãŠãŒã¶ãŒã«ã¯ããµã€ãã®å€ãããŒãžã§ã³ãæäŸãããŸãã
- æ©èœãžã®ä¿¡é Œãé«ãŸãã«ã€ããŠããšããžé¢æ°ã®èš±å¯ãªã¹ãã«ããã«å€ãã®åœã远å ãããå¶åŸ¡ãããæ®µéçãªããŒã«ã¢ãŠããå¯èœã«ãªããŸãã
å®è£ ã¬ã€ãïŒã³ãŒãã¬ãã«ã®äŸ
çè«ã¯çŽ æŽãããã§ãããå®éã«ã©ã®ããã«èŠãããèŠãŠã¿ãŸããããéåžžã«äººæ°ã®ããå®è£ ã§ããVercelã®Edge Functionsã§å®è¡ãããNext.js Middlewareã®æ§æã䜿çšããŸããæŠå¿µã¯Cloudflare WorkersãNetlify Edge Functionsã®ãããªä»ã®ãããã€ããŒã«ãç°¡åã«å¿çšã§ããŸãã
ã·ããªãªïŒæ¬¡ã®ãããªã«ãŒãã£ã³ã°ã·ã¹ãã ãæ§ç¯ããããšèããŠããŸãïŒ
- ã«ããã®ãŠãŒã¶ãŒïŒ`/`ïŒãå°çšã®ã«ããçãµã€ãïŒ`/ca`ïŒã«ãªãã€ã¬ã¯ãããã
- ãã€ããšãã©ã³ã¹ããã®ãã¹ãŠã®ãŠãŒã¶ãŒãã`/api/*`ãžã®APIåŒã³åºãã®ããã«ãšãŒãããåºæã®ããã¯ãšã³ãã«éãã«ã«ãŒãã£ã³ã°ããã
- ã³ãŒã'XX'ãæã€æ¶ç©ºã®åœããã®ãŠãŒã¶ãŒã®ã¢ã¯ã»ã¹ããããã¯ããã
Next.jsãããžã§ã¯ãã®ã«ãŒãã¬ãã«ïŒãŸãã¯`src/`å ïŒã«`middleware.ts`ãšããååã®ãã¡ã€ã«ãäœæããŸãã
// src/middleware.ts import { NextRequest, NextResponse } from 'next/server'; // ãã®ãªã¹ãã¯å¥ã®èšå®ãã¡ã€ã«ããšããžããŒã¿ããŒã¹ã§ç®¡çã§ããŸã const EU_COUNTRIES = ['DE', 'FR']; export const config = { // matcher ã¯ããã®ããã«ãŠã§ã¢ãå®è¡ããããã¹ãæå®ããŸãã matcher: ['/', '/about', '/api/:path*'], }; export function middleware(request: NextRequest) { // 1. ãªã¯ãšã¹ãããå°çããŒã¿ãæœåºããŸãã // `geo` ãªããžã§ã¯ãã¯Vercel Edge Networkã«ãã£ãŠèªåçã«å ¥åãããŸãã const { geo } = request; const country = geo?.country || 'US'; // å Žæãäžæãªå Žå㯠'US' ã«ãã©ãŒã«ããã¯ããŸã const pathname = request.nextUrl.pathname; // 2. ããžãã¯ïŒç¹å®ã®åœããã®ã¢ã¯ã»ã¹ããããã¯ãã if (country === 'XX') { // 403 Forbiddenã¬ã¹ãã³ã¹ãè¿ããŸãã return new NextResponse(null, { status: 403, statusText: "Forbidden" }); } // 3. ããžãã¯ïŒã«ããã®ãŠãŒã¶ãŒã /ca ãµããã¹ã«ãªãã€ã¬ã¯ããã // ãªãã€ã¬ã¯ãã«ãŒããé¿ããããã«ããã§ã« /ca ãã¹ã«ããªãããšã確èªããŸãã if (country === 'CA' && !pathname.startsWith('/ca')) { const url = request.nextUrl.clone(); url.pathname = `/ca${pathname}`; // 307 Temporary Redirect ã¬ã¹ãã³ã¹ãè¿ããŸãã return NextResponse.redirect(url); } // 4. ããžãã¯ïŒEUãŠãŒã¶ãŒã®APIãªã¯ãšã¹ãããªãŒãžã§ãã«ããã¯ãšã³ãã«ãªã©ã€ããã if (pathname.startsWith('/api') && EU_COUNTRIES.includes(country)) { const url = new URL(request.url); // ãã¹ãåãEUåºæã®ãªãªãžã³ãæãããã«å€æŽããŸãã url.hostname = 'api.eu.your-service.com'; console.log(`Rewriting API request for user in ${country} to ${url.hostname}`); // ãªã©ã€ããè¿ããŸãããŠãŒã¶ãŒã®ãã©ãŠã¶ã®URLã¯å€æŽãããŸããã return NextResponse.rewrite(url); } // 5. ã©ã®ã«ãŒã«ã«ãäžèŽããªãå Žåããªã¯ãšã¹ããããŒãžãŸãã¯APIã«ãŒãã«ç¶è¡ãããŸãã return NextResponse.next(); }
ã³ãŒãã®è§£èª¬ïŒ
- `config.matcher`ïŒããã¯éèŠãªæé©åã§ãããšããžãããã¯ãŒã¯ã«å¯Ÿãããã®é¢æ°ãç¹å®ã®ãã¹ã«å¯ŸããŠã®ã¿åŒã³åºãããã«æç€ºããç»åãCSSãã¡ã€ã«ãªã©ã®ã¢ã»ããã®å®è¡ã³ã¹ããç¯çŽããŸãã
- `request.geo`ïŒãã®ãªããžã§ã¯ãã¯ããã©ãããã©ãŒã ã«ãã£ãŠæäŸãããäœçœ®ããŒã¿ã®ä¿¡é Œã§ããæ å ±æºã§ãã`country`ã³ãŒããååŸããé©åãªããã©ã«ãå€ãæäŸããŸãã
- ããããã³ã°ããžãã¯ïŒåã«`403`ã¹ããŒã¿ã¹ã®`NextResponse`ãè¿ããŠããªã¯ãšã¹ãããšããžã§å³åº§ã«ãããã¯ããŸãããªãªãžã³ãµãŒããŒã¯äžåè§ŠããããŸããã
- ãªãã€ã¬ã¯ãããžãã¯ïŒ`NextResponse.redirect()`ã䜿çšããŸããããã¯307ã¬ã¹ãã³ã¹ããã©ãŠã¶ã«éãè¿ããæ°ããURLïŒ`/ca`ïŒããªã¯ãšã¹ãããããã«æç€ºããŸããããã¯ãŠãŒã¶ãŒã«èŠããŸãã
- ãªã©ã€ãããžãã¯ïŒ`NextResponse.rewrite()`ã䜿çšããŸããããã¯æã匷åãªã¢ã¯ã·ã§ã³ã§ãããšããžãããã¯ãŒã¯ã«ãç°ãªãURLïŒ`api.eu.your-service.com`ïŒããã³ã³ãã³ããååŸããå ã®URLïŒ`/api/...`ïŒã®äžã§æäŸããããã«æç€ºããŸããããã¯ãšã³ããŠãŒã¶ãŒã«ã¯å®å šã«ééçã§ãã
課é¡ãšèæ ®äºé
匷åã§ããäžæ¹ã§ããšããžã§ã®å°ççã«ãŒãã£ã³ã°ã®å®è£ ã«ã¯è€éãã䌎ããŸããèæ ®ãã¹ãéèŠãªèŠçŽ ãããã€ã玹ä»ããŸãïŒ
1. GeoIPããŒã¿ããŒã¹ã®æ£ç¢ºæ§
äœçœ®ããŒã¿ã¯ããŠãŒã¶ãŒã®IPã¢ãã¬ã¹ãGeoIPããŒã¿ããŒã¹ãšãããã³ã°ããããšã«ãã£ãŠå°ãåºãããŸãããããã®ããŒã¿ããŒã¹ã¯éåžžã«æ£ç¢ºã§ããã絶察ã§ã¯ãããŸãããVPNãã¢ãã€ã«ãããã¯ãŒã¯ããŸãã¯ç¹å®ã®äŒæ¥ãããã¯ãŒã¯äžã®ãŠãŒã¶ãŒã¯èª€ã£ãŠèå¥ãããå¯èœæ§ããããŸãããããã£ãŠãåžžã«ãŠãŒã¶ãŒãæ€åºãããå Žæãæåã§äžæžãããæ¹æ³ïŒäŸïŒãµã€ãã®ããã¿ãŒã«ããåœã»ã¬ã¯ã¿ãŒïŒãæäŸããå¿ èŠããããŸãã
2. ãã£ãã·ã¥ã®è€éã
åãURLã«å¯ŸããŠç°ãªãå°åã®ãŠãŒã¶ãŒã«ç°ãªãã³ã³ãã³ããæäŸããå Žåãããåœã®ãŠãŒã¶ãŒãå¥ã®åœåãã®ãã£ãã·ã¥ãããã³ã³ãã³ããèŠããªã¹ã¯ããããŸãããããé²ãã«ã¯ãCDNã«ããŒãžã®ç°ãªãããŒãžã§ã³ããã£ãã·ã¥ããããã«æç€ºããå¿ èŠããããŸããããã¯éåžžãã¬ã¹ãã³ã¹ã«`Vary`ããããŒãéä¿¡ããããšã§è¡ãããŸããäŸãã°ã`Vary: x-vercel-ip-country`ã¯ãCDNã«åœããšã«å¥ã ã®ãã£ãã·ã¥ãšã³ããªãäœæããããã«æç€ºããŸãã
3. ãã¹ããšãããã°
ãã€ãã«è¡ããã«ãã€ãã®ã«ãŒãã£ã³ã°ããžãã¯ãæ£ããæ©èœããããšãã©ã®ããã«ãã¹ãããŸããïŒããã¯é£ããå ŽåããããŸããæ¹æ³ã«ã¯ä»¥äžãå«ãŸããŸãïŒ
- VPNïŒVPNã䜿çšããŠã察象åœã®ãµãŒããŒãä»ããŠãã©ãã£ãã¯ããã³ããªã³ã°ããã®ã¯äžè¬çãªã¢ãããŒãã§ãã
- ãã©ãããã©ãŒã ãšãã¥ã¬ãŒã·ã§ã³ïŒVercelãªã©ã®äžéšã®ãã©ãããã©ãŒã ã§ã¯ããã¹ãç®çã§éçºäžã«`request.geo`ããŒã¿ãããŒã«ã«ã§äžæžãã§ããŸãã
- ãã©ãŠã¶éçºè ããŒã«ïŒäžéšã®ãã©ãŠã¶éçºè ããŒã«ã«ã¯äœçœ®æ å ±ãåœè£ ããæ©èœããããŸããããããåžžã«ãšããžã§ã®IPããŒã¹ã®æ€åºã«åœ±é¿ãäžãããšã¯éããŸããã
4. ãã³ããŒåºæã®å®è£
ãšããžã«ãŒãã£ã³ã°ã®æ žãšãªãæŠå¿µã¯æ®éçã§ãããå®è£ ã®è©³çްã¯ãããã€ããŒã«ãã£ãŠç°ãªããŸããVercelã¯`request.geo`ã䜿çšããCloudflareã¯`request.cf`ãªããžã§ã¯ãã®ããããã£ã䜿çšãããªã©ã§ããããžãã¯ã®ç§»è¡ã¯å¯èœã§ãããåçŽãªã³ããŒïŒããŒã¹ãæäœã§ã¯ãªããããçšåºŠã®ãã³ããŒããã¯ã€ã³ãååšããããšã«æ³šæããŠãã ããã
ãšããžã®æªæ¥ã¯å°çæ å ±ã«ãã
ãšããžé¢æ°ã«ããå°ççã«ãŒãã£ã³ã°ã¯ãåãªãè³¢ããã¯ããã¯ä»¥äžã®ãã®ã§ãããã°ããŒãã«ãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããæ¹æ³ã«ãããæ ¹æ¬çãªå€åã§ãããšããžãã©ãããã©ãŒã ããã匷åã«ãªãã«ã€ããŠãããã«æŽç·Žãããæ©èœãæåŸ ã§ããŸãïŒ
- ãšããžããŒã¿ããŒã¹ïŒCloudflare D1ãVercel KVã®ãããªè£œåã«ãããããŒã¿èªäœããšããžã«ååšã§ããããã«ãªããŸããããã«ããããŠãŒã¶ãŒã®ãªã¯ãšã¹ããæå¯ãã®ãšããžé¢æ°ã«ã«ãŒãã£ã³ã°ãããã®é¢æ°ãåãç©ççãªå Žæã«ããããŒã¿ããŒã¹ããããŒã¿ãèªã¿æžãããããšã§ãäžæ¡ããªç§ã®ããŒã¿ããŒã¹ã¯ãšãªãå®çŸã§ããŸãã
- ããæ·±ãçµ±åïŒããã³ããšã³ããã¬ãŒã ã¯ãŒã¯ãšãšããžæ©èœã®éã®çµåãããã«ç·å¯ã«ãªããããå€ãã®è€éããæœè±¡åãããã°ããŒãã«ãã¡ãŒã¹ãéçºãããã©ã«ãã«ãªãããšãæåŸ ãããŸãã
- 匷åãããããŒãœãã©ã€ãŒãŒã·ã§ã³ïŒåœãè¶ ããŠãããã€ã¹ã¿ã€ããæ¥ç¶é床ãããã«ã¯æé垯ãªã©ããšããžã§å©çšå¯èœãªããå€ãã®èŠå ã«åºã¥ããŠã«ãŒãã£ã³ã°ã®æ±ºå®ãè¡ããããã€ããŒããŒãœãã©ã€ãºãããäœéšãæäŸãããããã«ãªããŸãã
çµè«ïŒäžçã®ããã«ããšããžããæ§ç¯ãã
ããã³ããšã³ããšããžé¢æ°ã«ããå°ççã«ãŒãã£ã³ã°ã¯ãéçºè ãã°ããŒãã«ãªèŠèŽè åãã«æ§ç¯ããéã®æãè€éãªèª²é¡ã®ããã€ãã解決ããåãäžããŸãããã±ãŒã·ã§ã³ããŒã¹ã®ããžãã¯ãäžå€®éæš©åã®ãµãŒããŒãã忣ãããã¯ãŒã¯ãšããžã«ç§»è¡ããããšã§ãããé«éã§ããã ãã§ãªããããã³ã³ãã©ã€ã¢ã³ã¹ã«æºæ ããå埩åããããæ·±ãããŒãœãã©ã€ãºãããã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ã§ããŸãã
ãŠãŒã¶ãŒã®å Žæã«åºã¥ããŠãªã¯ãšã¹ãããªã©ã€ãããªãã€ã¬ã¯ãã倿Žããèœåã¯ãæå°éã®é å»¶ã§ãã¹ãŠè¡ãããæ°ããã¬ãã«ã®ãŠãŒã¶ãŒäœéšãè§£ãæŸã¡ãŸããã€ã³ããªãžã§ã³ããªããŒã¿ã«ãŒãã£ã³ã°ã§ããŒã¿äž»æš©ãå°éããããšãããããŒã«ã©ã€ãºãããã³ã³ãã³ãã§ãŠãŒã¶ãŒãåã°ããããšãŸã§ãå¯èœæ§ã¯èšãç¥ããŸãããæ¬¡ã®ã¢ããªã±ãŒã·ã§ã³ãèšèšããéã«ã¯ããµãŒããŒãã©ãã«ãã¹ããããã ãã§ãªããã°ããŒãã«ãªãããã¯ãŒã¯ãšããžã掻çšããŠããŠãŒã¶ãŒããããŸãã«ãã®å Žæã§åœŒãã«å¿ããæ¹æ³ãèããŠãã ããã