{"id":15509745,"url":"https://github.com/willin/authing-remix","last_synced_at":"2025-08-19T06:33:54.839Z","repository":{"id":44724120,"uuid":"452106910","full_name":"willin/authing-remix","owner":"willin","description":"Simple Authing Authentication for Remix","archived":false,"fork":false,"pushed_at":"2022-06-17T09:36:22.000Z","size":89,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-08-08T09:43:17.318Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/willin.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}},"created_at":"2022-01-26T01:54:14.000Z","updated_at":"2025-02-24T06:01:11.000Z","dependencies_parsed_at":"2022-08-30T02:12:10.373Z","dependency_job_id":null,"html_url":"https://github.com/willin/authing-remix","commit_stats":null,"previous_names":["authing/authing-remix"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/willin/authing-remix","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willin%2Fauthing-remix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willin%2Fauthing-remix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willin%2Fauthing-remix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willin%2Fauthing-remix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/willin","download_url":"https://codeload.github.com/willin/authing-remix/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willin%2Fauthing-remix/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271113403,"owners_count":24701609,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-19T02:00:09.176Z","response_time":63,"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":[],"created_at":"2024-10-02T09:43:33.653Z","updated_at":"2025-08-19T06:33:54.810Z","avatar_url":"https://github.com/willin.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @authing/remix\n\n[![npm](https://img.shields.io/npm/v/@authing/remix.svg)](https://npmjs.org/package/@authing/remix) [![npm](https://img.shields.io/npm/dt/@authing/remix.svg)](https://npmjs.org/package/@authing/remix)\n\n[中文说明](./readme.zh.md)\n\nSimple Authing OIDC Authentication for Remix\n\n- [@authing/remix](#authingremix)\n  - [Functions](#functions)\n    - [isAuthenticated](#isauthenticated)\n  - [Loader Helpers](#loader-helpers)\n    - [createCallbackLoader](#createcallbackloader)\n    - [createLoginLoader](#createloginloader)\n    - [createLogoutLoader](#createlogoutloader)\n  - [Quick Start](#quick-start)\n    - [Add dependencies](#add-dependencies)\n    - [Config](#config)\n    - [Create SessionStorage](#create-sessionstorage)\n    - [Create Login, Logout, Callback](#create-login-logout-callback)\n    - [Use in router](#use-in-router)\n  - [LICENSE](#license)\n\n## Functions\n\n### isAuthenticated\n\n```ts\nfunction isAuthenticated\u003cUser = any\u003e(\n  request: Request,\n  sessionStorage: SessionStorage,\n  options?: IsAuthenticatedOptions\n): Promise\u003cUser\u003e;\n\ntype IsAuthenticatedOptions = {\n  failureRedirect?: string;\n  successRedirect?: string;\n  throwOnError?: boolean;\n};\n```\n\nParams:\n\n- `throwOnError`: throw error when not authenticated\n- `failureRedirect`: redirect when not authenticated,such as `/login`\n- `successRedirect`: redirect when authenticated, such as `/dashboard`\n\nReturn Type: `User`\n\n## Loader Helpers\n\n### createCallbackLoader\n\n```ts\nfunction createCallbackLoader({\n  appDomain,\n  clientId,\n  clientSecret,\n  failureRedirect,\n  sessionStorage,\n  successRedirect\n}: CallbackLoaderArgs): LoaderFunction;\n\ntype CallbackLoaderArgs = {\n  appDomain: string;\n  clientId: string;\n  clientSecret: string;\n  sessionStorage: SessionStorage;\n  failureRedirect: string;\n  successRedirect: string;\n};\n```\n\nParams:\n\n- `appDomain`: App Domain, like: `https://your-app.authing.cn`\n- `clientId`: App ID\n- `clientSecret`: App Secret\n- `sessionStorage`: Remix SessionStorage\n  - Notice: If you are using Remix v1.1.3 or earlier, please do not use CookieSession, it may cause UTF-8 encoding parsing error\n- `failureRedirect`: redirect when failed, such as `/error`\n- `successRedirect`: redirect when success, such as `/dashboard`\n\n### createLoginLoader\n\n```ts\nfunction createLoginLoader({\n  appDomain,\n  clientId,\n  redirectUri,\n  scope\n}: LoginLoaderArgs): LoaderFunction;\n\ntype LoginLoaderArgs = {\n  appDomain: string;\n  ssoDomain?: string;\n  clientId: string;\n  redirectUri: string;\n  scope: string;\n};\n```\n\nParams:\n\n- `appDomain`: App Domain, like: `https://your-app.authing.cn`\n- `ssoDomain`: SSO Domain, like: `https://your-sso.authing.cn`, when set, `appDomain` will be ignored.\n- `clientId`: App ID\n- `redirectUri`: Callback Redirect URI (same with Authing console configuration)\n- `sope`: OAuth Scope, like: `openid profile email`\n  - Ref: [Documentation](https://docs.authing.cn/v2/concepts/oidc-common-questions.html#scope-%E5%8F%82%E6%95%B0%E5%AF%B9%E5%BA%94%E7%9A%84%E7%94%A8%E6%88%B7%E4%BF%A1%E6%81%AF)\n\n### createLogoutLoader\n\n```ts\nfunction createLogoutLoader({\n  redirectUri,\n  appDomain,\n  sessionStorage\n}: LogoutLoaderArgs): LoaderFunction;\n\ntype LogoutLoaderArgs = {\n  redirectUri: string;\n  appDomain: string;\n  sessionStorage: SessionStorage;\n};\n```\n\nParams:\n\n- `appDomain`: App Domain, like: `https://your-app.authing.cn`\n- `redirectUri`: Logout Callback Redirect URI (same in authing console)\n- `sessionStorage`: Remix SessionStorage\n\n## Quick Start\n\nExample project at `examples/basic`.\n\n### Add dependencies\n\n```bash\nnpm install --save @authing/remix\n# or\nyarn add @authing/remix\n```\n\n### Config\n\nPlaced in `app/config.server.ts` or somewhere else.\n\n```ts\nexport const clientId =\n  process.env.AUTHING_CLIENT_ID || '61e4da899687d7055442f6b7';\nexport const clientSecret = process.env.AUTHING_CLIENT_SECRET || '';\nexport const appDomain =\n  process.env.AUTHING_CLIENT_DOMAIN || 'https://remix.authing.cn';\nexport const redirectUri =\n  process.env.AUTHING_REDIRECT_URI || 'http://localhost:3000/authing/callback';\nexport const logoutRedirectUri =\n  process.env.AUTHING_LOGOUT_REDIRECT_URI || 'http://localhost:3000/';\n```\n\n### Create SessionStorage\n\nCreate `app/services/session.server.ts`.\n\nNotice: If you are using Remix v1.1.3 or earlier, please do not use CookieSession, it may cause UTF-8 encoding parsing error\n\n### Create Login, Logout, Callback\n\nCreate `app/routes/login.tsx`:\n\n```ts\nimport { createLoginLoader } from '@authing/remix';\nimport { appDomain, clientId, redirectUri } from '~/config.server';\n\nexport const loader = createLoginLoader({\n  appDomain,\n  clientId,\n  redirectUri,\n  scope: 'openid roles username phone profile'\n});\n```\n\nCreate `app/routes/logout.tsx`:\n\n```ts\nimport { createLogoutLoader } from '@authing/remix';\nimport { sessionStorage } from '~/services/session.server';\nimport { appDomain, logoutRedirectUri } from '~/config.server';\n\nexport const loader = createLogoutLoader({\n  redirectUri: logoutRedirectUri,\n  appDomain,\n  sessionStorage\n});\n```\n\nCreate `app/routes/authing/callback.tsx`:\n\n```ts\nimport { createCallbackLoader } from '@authing/remix';\nimport { sessionStorage } from '~/services/session.server';\nimport { appDomain, clientId, clientSecret } from '~/config.server';\n\nexport const loader = createCallbackLoader({\n  appDomain,\n  clientId,\n  clientSecret,\n  // 登录失败返回登录页\n  failureRedirect: '/error',\n  successRedirect: '/user',\n  sessionStorage\n});\n```\n\n### Use in router\n\n```ts\nimport { isAuthenticated } from '@authing/remix';\n\nexport const loader: LoaderFunction = async ({ request }) =\u003e {\n  const user = await isAuthenticated(request, sessionStorage);\n\n  return json(user || {});\n};\n\n// in page component:\nconst user = useLoaderData();\n```\n\n## LICENSE\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillin%2Fauthing-remix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwillin%2Fauthing-remix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillin%2Fauthing-remix/lists"}