ã»ãã·ã§ã³ã¹ãã¬ã¼ã¸ãªãã§ãã°ã¤ã³ã»ãã·ã§ã³ãç¶æããä»çµã¿ãä½ã£ãã®ã§ãç°¡åã«ç´¹ä»ãã¾ãã
å
æ¥oidc-auth ã¨ããHono ã®ããã«ã¦ã§ã¢ ãå®è£
ãã¦3rd-party middlewareã¨ãã¦æ¡ç¨ãã¦ããã ãã¾ãã ãããã¯å¤é¨IDãããã¤ãã¼ã§èªè¨¼ãè¡ãªããèªåçºè¡ããJWTãæ¯ãªã¯ã¨ã¹ ãæ¤è¨¼ãããã¨ã§ããµã¼ãå´ã§ã»ãã·ã§ã³IDãè¨é²ãããã¨ãªããã°ã¤ã³ã»ãã·ã§ã³ãç¶æãããã®ã§ãã
ãã®ã»ãã·ã§ã³ã¹ãã¬ã¼ã¸ä¸è¦ã¨ããç¹å¾´ã¯CDN ã¨ãã¸ã¨è¦ªåæ§ãé«ãããã¨ãã°Cloudflare Pagesã§æä¾ããéçã³ã³ãã³ãã«Google èªè¨¼ãã¤ãããã¨ãã£ããã¨ãã¨ãã¸ã®CPUã ãã§å®ç¾ã§ãã¾ããå ãã¦ãHonoã®ãã¼ã¿ããªãã£ã®ãããã§Deno Deployã§ãåãä»çµã¿ã使ããããã¾ãã
å人çã«ã¯å®ç¨æ§ã¨ã»ãã¥ãªãã£ã両ç«ããé¢ç½ããã®ãä½ããã¨èãã¦ãã¾ãããã»ãã¥ãªãã£é¢ã§ä¸å®ãæãã人ãããã¨æãã®ã§è§£èª¬è¨äºãæ¸ãã¦ã¿ã¾ãã
ã¨ãã¸ã³ã³ãã¥ã¼ãã£ã³ã°ã¨ã¯
æ¬é¡ã«å
¥ãåã«ãã¨ãã¸ã³ã³ãã¥ã¼ãã£ã³ã°ã«ã¤ãã¦ç°¡åã«ç´¹ä»ãã¾ãã
Webã®æèã§ã¨ãã¸ã³ã³ãã¥ã¼ãã£ã³ã°ã¨è¨ã£ãå ´åãããçæéã ãåããããªå¦çãCDN ã¨ãã¸ãµã¼ããªã©ã¦ã¼ã¶ã¼ã®è¿æã§åä½ãããä»çµã¿ãæãã¨æãã¾ããCloudflare Workers ãLambda@Edge ãVercel ãªã©ããã®ä»£è¡¨æ ¼ã¨è¨ããã§ãããã
ããããç°å¢ã®åä½ç°å¢ã¨ãã¦JavaScript ã¨ã³ã¸ã³ãå¤ãæ¡ç¨ããã¦ãããããã¨ãã¸ä¸ã§åããã¹ã¯ãªãã ã¯åºæ¬çã«JavaScript ãTypeScriptã§è¨è¿°ãããã¨ã«ãªãã¾ã1 ã
ã¦ã¼ã¹ã±ã¼ã¹ ã¨ãã¦ã¯ç°¡åãªå¦çãåæã¨ãã¦ãããã¨ãå¤ããã©ã®ç°å¢ã§ãå®è¡æéã®ä¸éã¯å³ããã§ããä¾ãã°Cloudflare Workersã¯å®è¡æéã®ä¸éã50ms2 ã§ãã
ããå¤ãææ¸ã§ããã@yusukebeããã®ãCDNã®ã¨ãã¸ã§å®è¡ããç³»ãé¢ç½ã ããèªãã¨èæ¯ãã¦ã¼ã¹ã±ã¼ã¹ ããã詳ããç解ã§ããã¨æãã¾ãã
ãã®ã¨ãã¸ã³ã³ãã¥ã¼ãã£ã³ã°ã§ãããç¹ã«Webããã³ãã¨ã³ãçéã®æ¹ã
ã«æ¯æããã¦ããå°è±¡ãããã¾ããç§ã¯éå¤æ¼¢ãªã®ã§æ³åã«ãªãã¾ãããå©ç¨è¨èªã®è¦ªåæ§ã¨å®éã®ãã¼ãºã¨ä¸¡æ¹ãåã¿åã£ã¦ããã¨ãããã¨ãªã®ã§ããããç¹ã«ãã¨ãã¸ã§SSR ããçµæãä¸å®æéãã£ãã·ã¥ãã¦ãããããªä½¿ãæ¹ã¯ã¡ãªããã大ãããã§ãã
Honoã®ç´¹ä»ã¨oidc-authã®å©ç¨ä¾
Honoã¯@yusukebeãããä½ããã¦ããTypeScript製ã®Webã¢ããªã±ã¼ã·ã§ã³ãã¬ã¼ã ã¯ã¼ã¯ ã§ãã
Honoã®ç¹å¾´ãä¸è¨ã§èª¬æããã¨ããäºæ¥è
ãã¨ã®å·®åã大ããã¨ãã¸å¦çã«ãã¼ã¿ããªãã£ãæä¾ããã¨ãã¸ç¨ãã¬ã¼ã ã¯ã¼ã¯ ãã¨ãªãã¾ã3 ãå社ã®ã¨ãã¸ã³ã³ãã¥ã¼ãã£ã³ã°ç°å¢ã¯åºæ¬çã«JavaScript /TypeScriptã§è¨è¿°ãããã®ãå¤ãã®ã§ãããããããã®å·®åãããªã大ãããè¤æ°ç¤¾ã®ç°å¢ã§åå
容ã®å¦çãæ¸ãã ãã§ãæå¤ã¨è¦å´ããå°è±¡ã§ããHonoã§æ¸ããã¨ã§å°ããå¤æ´ã§å¥ã®ç°å¢ã§ãåãããã¨ãã§ãã¾ãã
è«ãã証æ ã§ãä»åç§ãä½æããoidc-authã使ã£ã¦éçãã¼ã¸ã«OpenID Connectã§èªè¨¼ã»èªå¯ãã¤ããã³ã¼ããè¦ã¦ã¿ã¾ããããCloudflare Pagesã®å ´åã¯ä¸è¨ã®ããã«ãªãã¾ãã
import { Hono } from 'hono'
import { oidcAuthMiddleware, getAuth } from '@hono/oidc-auth'
const app = new Hono()
app.use('*' , oidcAuthMiddleware())
app.use('*' , async (c , next ) => {
const auth = await getAuth(c)
if (!auth?.email.endsWith ('@gmail.com' )) {
return c.text('Unauthorized' , 401 )
}
await next()
} )
app.get ('*' , async (c ) => {
const response = await c.env.ASSETS.fetch (c.req.raw);
const newResponse = new Response (response.body , response)
return newResponse
} );
export default app
èªè¨¼ç¨ã®URLãã¯ã©ã¤ã¢ã³ãIDãã·ã¼ã¯ã¬ãããªã©ã¯ç°å¢å¤æ° çµç±ã§æ¸¡ãã¦ãã¾ããä¸è¨ã®å ´åã§ããã°Google èªè¨¼ãçµç±ãã¦@gmail.com ã®ã¢ãã¬ã¹ã ã£ãå ´åã ãéçãã¼ã¸ãé²è¦§ã§ãã¾ãã
次ã«Deno Deployçãè¦ã¦ã¿ã¾ãããã
import { Hono } from 'npm:hono'
import { serveStatic } from 'npm:hono/deno'
import { oidcAuthMiddleware, getAuth } from 'npm:@hono/oidc-auth' ;
const app = new Hono()
app.use('*' , oidcAuthMiddleware())
app.use('*' , async (c , next ) => {
const auth = await getAuth(c)
if (!auth?.email.endsWith ('@gmail.com' )) {
return c.text('Unauthorized' , 401 )
}
await next()
} )
app.use('*' , serveStatic({ root : 'public/' } ))
Deno.serve(app.fetch )
ç°ãªãç°å¢ã§ä¼¼ãã³ã¼ããåããã¨ããããã¨æãã¾ãã
å®éã®æåãã½ã¼ã¹ã³ã¼ã ã確èªãããæ¹ã¯ä¸è¨ãªã³ã¯ãã試ãã¦ã¿ã¦ãã ããã
ãèªèº«ã§åä½ç¢ºèªãããå ´åãç°å¢å¤æ° ãæä½5ã¤è¨å®ããä¸ã§IDãããã¤ãå´ã«ã³ã¼ã«ããã¯URLãç»é²ããå¿
è¦ãããã¾ãã詳細ã¯@hono/oidc-auth ãã確èªãã ããã
JWTã«ããã»ãã·ã§ã³ç®¡çã®å®è£
ããããæ¬é¡ã§ããoidc-authã®å®è£
ãç´¹ä»ãã¾ãã
oidc-authã®ã·ã¼ã±ã³ã¹å³
ã·ã¼ã±ã³ã¹å³ãè¦ãã¨å°ãè¤éã«è¦ãã¾ãããIDãããã¤ãããIDãã¼ã¯ ã³ãåãåºãã¨ããã¾ã§ã¯æ®éã®OpenID Connectã®èªè¨¼ããã¼ã§ãã
ãã®å¾ãåãåºããIDãã¼ã¯ ã³ãå
ã«èªåã§JWTãä½ãã¾ãããã®JWTã«ã¯ã¦ã¼ã¶ã¼ID4 ãeã¡ã¼ã«ã¢ãã¬ã¹ããªãã¬ãã·ã¥ãã¼ã¯ ã³ããªãã¬ãã·ã¥æéï¼ããã©ã«ã15åï¼ã¨ã»ãã·ã§ã³æéï¼ããã©ã«ã1æ¥ï¼ãå«ã¾ãã¦ãããHS256ã§ç½²åãã¦ãã¾ãã
ãã®JWTãSet-Cookie ãããã§ãã©ã¦ã¶ã«è¿ãããã©ã¦ã¶ããéä¿¡ãããJWTãæ¯ãªã¯ã¨ã¹ ãæ¤è¨¼ãã¾ããJWTã®ç½²åæ¤è¨¼ããã¹ãã¦JWTå
ã®ã»ãã·ã§ã³æéãçµéãã¦ããªããã°ã»ãã·ã§ã³ãæå¹ã¨ãããã¨ã«ãªãã¾ãã
ä¸è¨ã®èª¬æãããããããã»ãã·ã§ã³ã¹ãã¬ã¼ã¸ã使ã£ã¦ããªãã®ãããããã¨æãã¾ããæ¬æ¥ãªãã»ãã·ã§ã³ã¹ãã¬ã¼ã¸ã«ããã¹ãæ
å ±ãç½²åä»ãã§ãã©ã¦ã¶ã®ã¯ããã¼ã«ä¿åããæ¯åç½²åæ¤è¨¼ãè¡ãªã£ã¦ããããã§ãã
ã»ãã¥ãªãã£ã«ãé
æ
®ãã¦å®è£
ãã¦ãã¾ããoidc-authã§ã¯oauth4webapi ã¨ãããã©ã¦ã¶åãã®OAuthã¯ã©ã¤ã¢ã³ãå®è£
ãå©ç¨ãã¦ãããOpenID Connectã®å®è£
ã§å¿
è¦ã¨ãããã»ãã¥ãªãã£å¯¾çã¯å
¨ã¦å®æ½ãã¦ãã¾ã5 ãã¾ããã¯ããã¼ã®Secureå±æ§ãHttpOnlyå±æ§ãã¡ããã¨æå®ãã¦ãã¾ãã
JWTãã»ãã·ã§ã³ã¨ãã¦ä½¿ããã¨ã®æ¯éã«ã¤ãã¦
5å¹´ã»ã©åã«ãSPAãªã©ã®æèã§JWTãã»ãã·ã§ã³ç®¡çã«ä½¿ãã®ãããã®ãæªãã®ããè°è«ã«ãªã£ããã¨ãããã¾ãããã¨ãã°ãã©ããã¦ãªã¹ã¯ã¢ã»ã¹ã¡ã³ãããã« JWT ãã»ãã·ã§ã³ã«ä½¿ã£ã¡ããããï¼ ããªã©ãèªãã¨å½æã®è°è«ããããã¾ãã
ç§ã®ç解ã§ã¯ãã»ãã·ã§ã³ç®¡çã«JWTã使ãã¹ããããªãæ´¾ã®ä¸»å¼µã¯æ¬¡ã®ããã«ã¾ã¨ãããã¾ãã
ä¸ä¸JWTãæ¼æ´©ããã¨ãã«ã»ãã·ã§ã³ãç¡å¹åããæ段ããªããJWTã®æå¹æéåããå¾
ã¤ãããªã
ãã°ã¢ã¦ãæã«å½è©²JWTãç¡å¹åã§ããªãï¼ããããå®è£
ãå¤ãï¼
å
é¨ç¯ãJWTç½²åç¨ã®å
±ééµãæªç¨ããã¨ä»»æã®JWTãä½ã£ã¦èªè¨¼ãåé¿ã§ãã
JWTã¯å·¨å¤§ãã¤æ¤è¨¼ã³ã¹ããé«ãã®ã§ãããã¯ã¼ã¯ã¨CPUã®ç¡é§é£ãã§ãã
JWTãæ¡ç¨ããã¨ã»ãã·ã§ã³IDæ¹å¼ããè¤é度ãä¸ãã£ã¦ãã°ãä½ãããã
ãããã®ææã®ãã¡ãç¹ã«æåã®ãã®ã¯è´å½çãªåé¡ç¹ã¨è¨ãã¾ããä¸å®è¦æ¨¡ã®çµç¹ã§ã®éç¨ãèããå ´åãå©ç¨è
ãPCãç´å¤±ãã¦JWTãæªæãã第ä¸è
ã«æ¸¡ãã·ããªãªã¯ç¾å®çãªè
å¨ã§ããä¸æ¹ãJWTã¯ç½²åæ¤è¨¼ããã¹ããã°JWTã®ä¸èº«ãä¿¡ç¨ããä»çµã¿ãªã®ã§ãJWTãæ¼æ´©ããå ´åã§ã管çè
ãç¡å¹åã§ããªãã®ã§ãã
ãã®åé¡ã«å¯¾å¿ãããããä»åå®è£
ããoidc-authã§ã¯JWTå
ã«ãªãã¬ãã·ã¥ãã¼ã¯ ã³ãæ ¼ç´ããæ¯è¼ççãã¹ãã³ï¼ããã©ã«ã15åï¼ã§æé»çã«ãã¼ã¯ ã³åçºè¡ãè¡ã£ã¦ãã¾ããJWTæ¼æ´©ã®æããããå ´åã管çè
ãå½è©²ã¦ã¼ã¶ã¼ã®ãªãã¬ãã·ã¥ãã¼ã¯ ã³ãç¡å¹åããã°15å以å
ã«ã¢ã¯ã»ã¹ã§ããªããªãã¨ããããã§ãã管çè
ããªãã¬ãã·ã¥ãã¼ã¯ ã³ãç¡å¹åã§ãããã©ããã¯IDãããã¤ãã¼ã«ããã¨æãã¾ãããGoogle WorkspaceãAuth0ãAWS Cognitoãªã©ã§ã¯ç¡å¹åå¯è½ã§ãã
ã¾ãã2ã¤ç®ã®ææç¹ã¸ã®å¯¾å¿ã¨ãã¦ãã°ã¢ã¦ãæã«JWTã«å«ã¾ãããªãã¬ãã·ã¥ãã¼ã¯ ã³ãç¡å¹åãã¦ãã¾ã6 ãããã«ãããJWTãä»®ã«æ¼æ´©ããã¨ãã¦ã次åã®ãã¼ã¯ ã³ãªãã¬ãã·ã¥ã«å¤±æãã¦JWTèªä½ãç¡å¹ã«ãªãä»çµã¿ã«ãªã£ã¦ãã¾ãããã§ã«èª¬æããéãã»ãã·ã§ã³ç¡å¹åã試ã¿ã¦ããä¸å®æéï¼ããã©ã«ã15åï¼ã®ã¿ã¤ã ã©ã°ã許容ããåæãªã®ã§ãã¿ã¤ã ã©ã°1åã§ã許ããªãå ´åã¯ãã®ä»çµã¿èªä½ãæ¡ç¨ã§ããªããã¨ã«ãªãã¾ãã
3ã¤ç®ã®ææç¹ãæ·±å»ãªå
容ã ã¨ç§ã¯èãã¦ãã¾ãã対çã¨ãã¦ã¯å®æçã«éµããã¼ãã¼ãããããããããªãã¨æãã¾ãããç¾ç¶ã ã¨éç¨è
ãé å¼µããããªãã®ã§ãoidc-authå´ã§ãä½ãä»çµã¿åãããã¨ããã§ãã
4ã¤ç®ã¯å¤§å¤ããã£ã¨ãã ã¨æãã®ã§ãããã¨ãã¸ã³ã³ãã¥ã¼ãã£ã³ã°ç°å¢ã ã¨ãããã¯ã¼ã¯è»¢ééã¨ã¨ãã¸ã®CPUã¯å®ä¾¡ãªãªã½ã¼ã¹ã§ãããã»ãã·ã§ã³ã¹ãã¬ã¼ã¸ã¯ç¸å¯¾çã«é«ä¾¡ãªã®ã§è¨±ãã¦ã»ãããã¨ããã®ãç§ã®ä¸»å¼µã§ãã
5ã¤ç®ãæ¬å½ã«ãã®éãã§ãã»ãã¥ãªãã£ã®å°éæ§ãä½ãå°äºç®ã®ãã¼ã ãJWTã使ã£ãã»ãã·ã§ã³ç®¡çãèªåå®è£
ããã®ã¯ä¸è¬è«ã¨ãã¦å±éºã ã¨æãã¾ããã¨ã¯ãããä»åç§ã¯ä¸å®ä»¥ä¸æ¤è¨ãã¦ä½ã£ãã¤ããã§ãããOSS ã®å½¢ã§ã¿ããªã§å©ãã¦ããã°å®å
¨ãªãã®ãã§ããã®ã§ã¯ãªãã§ããããããããããã¦ãã¦ãèç©ã§ããç°å¢ã¨ãã¦Honoã¯ç´ æ´ããããã©ãããã©ã¼ã ã ã¨æã£ã¦ãã¾ãã
ã¾ã¨ã
OpenID Connectã®ãã°ã¤ã³ã»ãã·ã§ã³ç¶æããã©ã¦ã¶ã¯ããã¼ã ãã§å®ç¾ãããããªHonoã®ããã«ã¦ã§ã¢ oidc-authãå®è£
ãã¾ãããCDN ã¨ãã¸ã¨ç¸æ§ãè¯ããå®ä¾¡ã«èªè¨¼ã»èªå¯ãå®ç¾ã§ãã¦ä¾¿å©ã ã¨æãã¾ããã¾ãã»ãã¥ãªãã£ã«ã¤ãã¦ãèæ
®ãã¦ããã¤ããã§ãã
ã¨ã¯ããoidc-authã«ã©ã®ç¨åº¦ã®ãã¼ãºããããä½è
èªèº«ãããããã£ã¦ãã¾ããã®ã§ã使ã£ã¦ã¿ã¦ã®ææ³ããæè¦ãããã ããã¨å¬ããã§ãã
æå¾ã«ãï¼ããããå¾ä½ã®ãããªãç¶æ
ã§ï¼oidc-authãHonoã®3rd-party middlewareã¨ãã¦æ¡ç¨ããã ãã@yusukebeããã«æè¬ãããã¾ãããã®è¨äºãå
ã«READMEã«è¿½è¨ãã¦ãããå°ãå®å¿ãã¦ä½¿ããç¶æ
ã«ãããã¨æãã¾ãã