Plugins

Discord

Official plugin — Discord sign-in where email can be real, verified, or legitimately absent.

Discord is OAuth2 with one quirk: /users/@me email can be null (phone-only accounts). oauth() signs those people in without an email instead of failing them.

The one rule

Keep the email scope in the request (it is on by default). Without it Discord never reports verified: true, and unverified emails cannot claim existing accounts.

Quick start

Create an application

Discord Developer Portal → Applications → New Application → OAuth2. Add a redirect under OAuth2 → Redirects: https://app.example.com/auth/oauth/callback/discord.

Plug it

src/app.ts
import { oke } from "okengine";
import { oauth } from "okengine/plugins";

export const app = oke({
  name: "shop",
  env: "dev",
  gate: { auth: {} },
}).plug(
  oauth({
    baseUrl: "https://app.example.com",
    providers: {
      discord: { enabled: true },
    },
  }),
);

Set the client secret

# .env.local
OAUTH_DISCORD_CLIENT_SECRET=...

How identity works

AspectBehavior
ProfileGET https://discord.com/api/users/@me (string id is the subject)
Emailtaken as-is when present; null flows through as no email
Email trustverified: true only; the flag silently going missing keeps the address unverified
Nameglobal_name, falling back to username

Consequence: an integration bug that drops the verified field degrades to unverified — never to falsely verified. That direction of failure is what keeps account takeover off the table.

Default scopes: identify, email. The authorize URL always carries prompt=consent.

Options

OptionTypeDefaultMeaning
enabledbooleanfalseTurn the provider on
clientIdstringVault/env*\*OAUTH_DISCORD_CLIENT_ID
redirectUristring{baseUrl}…/discordExact registered URI
scopesstring[]driver defaultsExtra scopes
storeProviderTokensbooleanfalseKeep tokens in Vault

Surfaces

FlowPath
StartPOST /auth/oauth/discord/start
CallbackGET+POST /auth/oauth/callback/discord
LinkPOST /auth/oauth/discord/link

Troubleshooting

Learn more

  • OAuth — shared flows and security model
  • GitHub — primary-email lookup pattern
  • Vault — where secrets live

Next

On this page