OpenAuth Documentation

repository·master·Indexed 27 days ago

https://github.com/anomalyco/openauth

A standards-based, self-hosted authentication provider implementing OAuth 2.0. Designed for deployment on Node.js, Bun, AWS Lambda, and Cloudflare Workers, OpenAuth serves web, mobile, and API applications. It features a decoupled user management system, support for third-party identity providers (Google, GitHub), and a themeable UI. The openauthjs package provides tools to initialize issuer servers, define type-safe subjects, and manage authorization flows using code flow for SSR or token flow with PKCE for SPAs.

Tokens
26.1K
Snippets
94
Records
177
Agent score
92%

What's inside OpenAuth

  1. Overview of OpenAuth

    master

    OpenAuth is a standards-based, self-hosted authentication provider designed for web apps, mobile apps, single-page apps (SPAs), APIs, and 3rd party clients. It is currently in beta.

    Key Features

    • Universal: Can be deployed as a standalone service or embedded into existing applications across any framework.
    • Self-hosted: Runs on your infrastructure, supporting Node.js, Bun, AWS Lambda, or Cloudflare Workers.
    • Standards-based: Implements the OAuth 2.0 specification, making it compatible with any OAuth client.
    • Customizable: Includes a themeable UI that can be customized or entirely replaced with your own implementation.
    • Identity Provider Support: Supports third-party providers (e.g., Google, GitHub) and built-in flows (e.g., email/password, pin code).
    • Decoupled User Management: OpenAuth does not manage user databases directly. Instead, it invokes a callback after successful identification, allowing you to implement your own user lookup or creation logic.
  2. Overview of OpenAuth capabilities

    master

    OpenAuth is a standards-based, self-hosted authentication provider designed to work across various platforms including web apps, mobile apps, SPAs, APIs, and 3rd party clients.

    Key Features

    • Universal: Deploy as a standalone service or embed into existing applications; compatible with any framework.
    • Self-hosted: Runs on your infrastructure (Node.js, Bun, AWS Lambda, or Cloudflare Workers).
    • Standards-based: Implements OAuth 2.0 specifications, allowing any OAuth client to use it for access and refresh tokens.
    • Customizable: Includes a themeable UI that can be customized or replaced with your own implementation.
  3. Understand the Starlight project structure

    master

    A standard Starlight project follows this directory structure:

    • src/content/docs/: Contains .md or .mdx files. Each file is automatically exposed as a route based on its filename.
    • src/assets/: Place images here to embed them in Markdown using relative links.
    • public/: Place static assets like favicons here.
    • astro.config.mjs: The Astro configuration file.
    • package.json: Project dependencies and scripts.
    • tsconfig.json: TypeScript configuration.
    .
    ├── public/
    ├── src/
    │   ├── assets/
    │   ├── content/
    │   │   ├── docs/
    │   │   └── config.ts
    │   └── env.d.ts
    ├── astro.config.mjs
    ├── package.json
    └── tsconfig.json
  4. Configure Cloudflare KV as a storage adapter

    master

    To use Cloudflare KV for OpenAuth storage, import CloudflareStorage from @openauthjs/openauth/storage/cloudflare and initialize it with a namespace option. The resulting storage instance can then be passed to the issuer configuration.

    import { CloudflareStorage } from "@openauthjs/openauth/storage/cloudflare"
    
    const storage = CloudflareStorage({
      namespace: "my-namespace"
    })
    
    export default issuer({
      storage,
      // ...
    })
  5. Use Token Flow with PKCE for SPAs and Mobile apps

    master

    For client-side applications without a backend, use the token flow with pkce: true. Use client.authorize to get a challenge and a URL, then use client.exchange with the verifier (stored during the challenge phase) to obtain tokens.

    // 1. Start flow and store challenge
    const { challenge, url } = await client.authorize(<redirect-uri>, "code", { pkce: true })
    localStorage.setItem("challenge", JSON.stringify(challenge))
    location.href = url
    
    // 2. Exchange code using the verifier
    const challengeData = JSON.parse(localStorage.getItem("challenge"))
    const exchanged = await client.exchange(
      query.get("code"),
      redirect_uri,
      challengeData.verifier,
    )
    
    if (exchanged.err) throw new Error("Invalid code")
    localStorage.setItem("access_token", exchanged.tokens.access)
    localStorage.setItem("refresh_token", exchanged.tokens.refresh)
  6. Define subject schemas for access tokens

    master

    Subjects define the shape of the data stored in the JWT access token. OpenAuth uses the standard-schema specification, allowing you to use libraries like Valibot or Zod (v3.24.0+).

    It is recommended to define subjects in a separate file so they can be shared between the server and the client.

    import { object, string } from "valibot"
    
    const subjects = createSubjects({
      user: object({
        userID: string(),
        workspaceID: string(),
      }),
    })
  7. Deploy the OpenAuth issuer server

    master

    The issuer function returns a Hono app. Deployment depends on your runtime:

    • Bun/Cloudflare: Use export default app.
    • AWS Lambda: Use hono/aws-lambda to wrap the app.
    • Node.js: Use @hono/node-server to serve the app.
    // Bun or Cloudflare
    export default app
    
    // Lambda
    import { handle } from "hono/aws-lambda"
    export const handler = handle(app)
    
    // Node.js
    import { serve } from "@hono/node-server"
    serve(app)
  8. Use XProvider to authenticate with X.com

    master

    Use the XProvider to implement authentication via X.com (formerly Twitter) in your OpenAuth issuer configuration. You must provide a clientID and clientSecret obtained from your X developer application.

    import { XProvider } from "@openauthjs/openauth/provider/x"
    
    export default issuer({
      providers: {
        x: XProvider({
          clientID: "1234567890",
          clientSecret: "0987654321"
        })
      }
    })
  9. Implement Auth Flow for SSR (Server-Side Rendering) sites

    master

    For sites with a server component, use the code flow:

    1. Authorize: Redirect the user using client.authorize(redirectUri, 'code').
    2. Exchange: After redirection, exchange the code query parameter for tokens using client.exchange(code, redirectUri).
    3. Verify: Use client.verify(subjects, accessToken) to validate the token. You can optionally pass a refresh token to automatically refresh expired access tokens.