Imported from gabrielmoreira/agent-skills-mirror (
mirrors/repos/medusajs@medusa/packages/modules/providers/auth-github/AGENTS.md). Install upstream withnpx skills add gabrielmoreira/agent-skills-mirror --skill auth-github. Copyright stays with the author.
@medusajs/auth-github
Auth Module provider for "Sign in with GitHub" using the OAuth 2 authorization-code flow.
Using this package
module.exports = defineConfig({
modules: [
{
resolve: "@medusajs/medusa/auth",
options: {
providers: [
// overriding `providers` drops the default emailpass provider, so re-add it
{
resolve: "@medusajs/medusa/auth-emailpass",
id: "emailpass",
},
{
resolve: "@medusajs/medusa/auth-github",
id: "github",
options: {
clientId: process.env.GITHUB_CLIENT_ID,
clientSecret: process.env.GITHUB_CLIENT_SECRET,
callbackUrl: process.env.GITHUB_CALLBACK_URL,
},
},
],
},
},
],
})
- Options (
GithubAuthProviderOptions):clientId,clientSecret,callbackUrl, all required (validateOptionsthrows at boot). - Flow:
POST /auth/{actor_type}/githubreturns{ location }to redirect the browser to; GitHub redirects to yourcallbackUrl(a storefront/admin page), which callsPOST /auth/{actor_type}/github/callbackwith thecodeandstatequery params. - Docs: https://docs.medusajs.com/resources/commerce-modules/auth/auth-providers/github.md
- Build a custom auth provider: https://docs.medusajs.com/resources/references/auth/provider.md
Architecture
src/services/github.ts:GithubAuthService extends AbstractAuthModuleProvider,static identifier = "github".- Implements
validateOptions,authenticate(stores a random state key viaauthIdentityService.setStateand returns the GitHub authorize URL),validateCallback(exchanges the code, fetcheshttps://api.github.com/user, upserts the identity).registerthrowsNOT_ALLOWED. - Reference for a custom OAuth redirect provider.
Development
yarn build,yarn testyarn test:integration:integration-tests/__tests__/services.spec.tsmocks GitHub withmsw.
Gotchas
entity_idis the GitHub numeric user ID (as a string), not the email.user_metadataholdsemail,name,avatar,profile_url,company,two_factor_authentication, copied from the GitHub/userresponse.- Tokens (
access_token,refresh_token, expiry timestamps) are saved inprovider_metadataand overwritten on every login. - A request body
callback_urloverrides the configuredcallbackUrlfor that flow; it's stored in state and reused in the token exchange. There is no allowlist (unlikeauth-oidc). - The callback must carry the
statequery param issued byauthenticate; if it's missing or no longer stored, it returns"No state provided, or session expired".
