{"id":23064136,"url":"https://github.com/gw31415/hono-oidc-simple","last_synced_at":"2026-05-17T02:05:46.176Z","repository":{"id":266952654,"uuid":"899857392","full_name":"gw31415/hono-oidc-simple","owner":"gw31415","description":"Simplifies the implementation of OIDC auth in Hono","archived":false,"fork":false,"pushed_at":"2025-04-28T14:48:58.000Z","size":83,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-14T22:53:21.827Z","etag":null,"topics":["honojs","oidc"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gw31415.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-12-07T07:39:54.000Z","updated_at":"2025-04-29T00:37:26.000Z","dependencies_parsed_at":null,"dependency_job_id":"8522c1ab-753f-4bab-b20e-2990d2a700c2","html_url":"https://github.com/gw31415/hono-oidc-simple","commit_stats":null,"previous_names":["gw31415/hono-oidc-simple"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/gw31415/hono-oidc-simple","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gw31415%2Fhono-oidc-simple","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gw31415%2Fhono-oidc-simple/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gw31415%2Fhono-oidc-simple/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gw31415%2Fhono-oidc-simple/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gw31415","download_url":"https://codeload.github.com/gw31415/hono-oidc-simple/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gw31415%2Fhono-oidc-simple/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33125184,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-16T18:38:32.183Z","status":"online","status_checked_at":"2026-05-17T02:00:05.366Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["honojs","oidc"],"created_at":"2024-12-16T04:16:12.400Z","updated_at":"2026-05-17T02:05:46.171Z","avatar_url":"https://github.com/gw31415.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @gw31415/hono-oidc-simple\n[![npm version](https://badge.fury.io/js/@gw31415%2Fhono-oidc-simple.svg?icon=si%3Anpm)](https://badge.fury.io/js/@gw31415%2Fhono-oidc-simple)\n[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n\n`@gw31415/hono-oidc-simple` simplifies the implementation of OpenID Connect\n(OIDC) authentication in Hono-based applications. It provides tools for managing\ntokens, user sessions, and handling login and logout easily.\n\n---\n\n## Features\n\n- Zero Dependency: No `dependencies` in `package.json`. Only `devDependencies` or\n  `peerDependencies` (`hono`) are used.\n- Middleware Creation: Provides middleware and handlers for managing user\n  authentication states.\n- Customizable: Abstract methods allow flexibility in how tokens are stored or\n  retrieved.\n- Multi-Runtime Support: Works with below runtimes:\n  - [x] Bun\n  - [x] Cloudflare Workers\n  - [x] Deno\n  - [x] Node.js\n\n## Installation\n\n```bash\nnpm i @gw31415/hono-oidc-simple\n```\n\n## Usage\n\nPlease check the example project: [`gw31415/hono-oidc-simple-example`](https://github.com/gw31415/hono-oidc-simple-example).\n\n### Setup and Create Middleware of OIDC\n\n```ts\n/** Cookie expiration period */\nconst COOKIE_MAXAGE = 60 * 60 * 24 * 30 * 6; // 6 months\n\n/** Set-up OIDC */\nconst oidc = OIDC((c) =\u003e {\n  const envs = env\u003c{\n    OIDC_GOOGLE_CLIENT: string;\n    OIDC_GOOGLE_SECRET: string;\n  }\u003e(c);\n  return {\n    issuers: [\n      {\n        issuer: \"https://accounts.google.com\",\n        authEndpoint: \"https://accounts.google.com/o/oauth2/v2/auth\",\n        tokenEndpoint: \"https://oauth2.googleapis.com/token\",\n        tokenRevocationEndpoint: \"https://oauth2.googleapis.com/revoke\",\n        useLocalJwt: false,\n        createClaims: async (c, tokens) =\u003e {\n          const idToken: string | undefined = await token.getIDToken(c);\n          if (idToken) {\n            const jwks = createRemoteJWKSet(\n              new URL(\"https://www.googleapis.com/oauth2/v3/certs\"),\n            );\n            try\n            {\n              const { payload } = await jwtVerify(idToken, jwks, {\n                issuer: \"https://accounts.google.com\",\n                audience: envs.OIDC_GOOGLE_CLIENT,\n              });\n              return payload as Claims;\n            } catch (e) {\n              console.error(e);\n            }\n          }\n          return undefined;\n        },\n        scopes: [\"openid\", \"email\", \"profile\"],\n        client_id: envs.OIDC_GOOGLE_CLIENT,\n        client_secret: envs.OIDC_GOOGLE_SECRET,\n      },\n    ],\n    getIssUrl: () =\u003e \"https://accounts.google.com\",\n    clientSideTokenStore: {\n      getRefreshToken: (c) =\u003e getCookie(c, \"refresh_token\"),\n      getIDToken: (c) =\u003e getCookie(c, \"jwt\"),\n      setRefreshToken: (c, token) =\u003e {\n        if (!token) {\n          deleteCookie(c, \"refresh_token\");\n          return;\n        }\n        const reqUrl = new URL(c.req.url);\n        const opts: CookieOptions = {\n          path: \"/\",\n          sameSite: \"Lax\",\n          httpOnly: true,\n          secure: reqUrl.hostname !== \"localhost\",\n          maxAge: COOKIE_MAXAGE,\n        };\n        setCookie(c, \"refresh_token\", token, opts);\n      },\n      setIDToken: (c, token) =\u003e {\n        if (!token) {\n          deleteCookie(c, \"jwt\");\n          return;\n        }\n        const reqUrl = new URL(c.req.url);\n        const secure = reqUrl.hostname !== \"localhost\";\n        return setCookie(c, \"jwt\", token, {\n          path: \"/\",\n          sameSite: \"Lax\",\n          httpOnly: true,\n          secure,\n          maxAge: COOKIE_MAXAGE,\n        });\n      },\n    },\n  };\n});\n```\n\n### Create your Middlewares to get the claims\n\n```ts\ntype Middleware = OIDCMiddlewareType\u003ctypeof oidc\u003e;\n\n/**\n * @param iss OIDC Issuer URL\n */\nexport const loginRoute = (iss: IssuerType\u003ctypeof oidc\u003e) =\u003e\n  createRoute(\n    oidc.loginHandler(iss, (res, c) =\u003e {\n      if (res.type === \"ERR\") {\n        const error = res.error;\n        switch (error) {\n          case \"Unauthorized\":\n            return c.redirect(\"/\");\n          case \"OAuthServerError\":\n            return c.text(`Error: ${error}`, { status: 500 });\n          default:\n            return c.text(\"Invalid state\", { status: 500 });\n        }\n      }\n      return c.redirect(\"/\");\n    }),\n  );\n\nexport const logoutRoute = createRoute(\n  oidc.logoutHandler((c) =\u003e {\n    return c.redirect(\"/\");\n  }),\n);\n\nexport const useClaims = oidc.useClaims;\n\n/** Middleware to specify pages that require login */\nexport const loginRequired: Middleware = every(useClaims, (async (c, next) =\u003e {\n  if (!c.var.claims) {\n    return c.render(\n      \u003cdiv className=\"font-sans size-full flex items-center justify-center\"\u003e\n        \u003cCard\u003e\n          \u003cCardHeader\u003e\n            \u003cCardTitle\u003eProtected Page\u003c/CardTitle\u003e\n          \u003c/CardHeader\u003e\n          \u003cCardContent\u003e\n            \u003cCardDescription\u003e\n              You must be logged in to view this page.\n            \u003c/CardDescription\u003e\n          \u003c/CardContent\u003e\n          \u003cCardFooter\u003e\n            \u003cButton asChild className=\"w-full\"\u003e\n              \u003ca href=\"/login\"\u003eLogin\u003c/a\u003e\n            \u003c/Button\u003e\n          \u003c/CardFooter\u003e\n        \u003c/Card\u003e\n      \u003c/div\u003e,\n      { title: \"Login Required\" },\n    );\n  }\n  return await next();\n}) satisfies Middleware);\n```\n\n## License\n\nApache-2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgw31415%2Fhono-oidc-simple","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgw31415%2Fhono-oidc-simple","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgw31415%2Fhono-oidc-simple/lists"}