AletheiaFact / AletheiaFact/aletheia
Enhancement: Add Google (and other social providers) login via Ory Kratos OIDC
- 主要言語
- TypeScript
- スター
- 55
- フォーク
- 20
- 平均マージ
- 2日 6時間
- マージ済み PR(30日)
- 2
説明
### Background Information
Today, the platform authenticates users through Ory Kratos using **password only**. Registration is fully app-driven: `UsersService.register()` (`server/users/users.service.ts`) creates the user in MongoDB first, then calls `OryService.createIdentity()` (`server/auth/ory/ory.service.ts`), which hits Kratos's **Admin API** directly to create the identity. The user later authenticates via Kratos's native `password` self-service flow, which is what actually issues the browser session cookie.
We want to let users sign in/sign up with a Google account (and potentially other social providers later, e.g. Facebook/GitHub).
Kratos (`v0.13.0`, see `docker-compose.yaml` / `ory_config/kratos.yml`) supports this via the `oidc` self-service method, but our current architecture doesn't use Kratos's native self-service flow at all for registration — it bypasses it via the Admin API. That pattern doesn't work for OIDC: the OAuth handshake with Google can only happen inside Kratos's native `oidc` flow (Kratos must redirect the browser to Google and back), and a browser session cookie can only be issued at the end of a native self-service flow — not through the Admin API alone.
To preserve our current registration business logic (creating the Mongo `User` doc, assigning default `role`/`namespace`, keeping Mongo as the source of truth per `identity.schema.json` traits: `email`, `user_id`, `role`, `app_affiliation`), we need to hook into the native flow instead of bypassing it: Kratos's `after.oidc.hooks` (web_hook type) can call a NestJS endpoint mid-flow, before the identity is persisted, letting our backend create the Mongo user and return the final traits.
### Steps to Reproduce
N/A — this is a feature request, not a reproducible bug. Current behavior: there is no way to log in or sign up with a Google/social account; only email + password is supported.
### How
1. **Google Cloud Console**: create an OAuth 2.0 client (web application), configure the authorized redirect URI to Kratos's public endpoint (`/self-service/methods/oidc/callback/google`).
2. **`ory_config/kratos.yml`**: add an `oidc` block under `selfservice.methods` with the Google provider config (client_id, client_secret, scopes: `email`, `profile`) and a Jsonnet mapper that maps the Google profile (`email`, `name`) into our identity traits.
3. **`ory_config/kratos.yml`**: add an `after.oidc.hooks` entry of type `web_hook` pointing at a new NestJS endpoint (e.g. `POST /auth/oidc-webhook`), so that on first login via Google, Kratos calls our backend before creating the identity.
4. **NestJS**: implement the webhook endpoint — reuses the existing logic from `UsersService.register()` (create Mongo `User`, assign default `role: Regular` / `namespace: main`, subscribe to notifications) and returns the traits (`user_id`, `role`, `app_affiliation`) the Kratos hook expects, so the identity gets created with the correct linkage to Mongo.
5. **Security**: protect the webhook endpoint (Kratos supports a shared auth header/basic auth for hook calls) so it can't be called by anyone else.
6. **Account linking**: decide behavior for a user who already has a password account with the same email trying to sign in with Google for the first time (Kratos supports linking via the `settings` flow).
7. **Frontend (`src/pages/sign-up.tsx` / `login` pages)**: add a "Continue with Google" button that redirects into Kratos's native `oidc` flow instead of our custom form submission.
8. **Tests**: unit tests for the webhook endpoint, e2e coverage of the OIDC login flow (mocking Google's OAuth response if feasible), and a manual QA pass for account linking edge cases.
### Expected Behavior
A user can click "Continue with Google" on the login/sign-up page, authenticate with their Google account, and land back on the platform fully logged in (valid Kratos session cookie), with a corresponding MongoDB `User` document created (if it didn't already exist) with a default role/namespace — mirroring what happens today for password-based registration, without requiring a separate password to be set.
コントリビューションガイド
このリポジトリのコントリビューションガイドは索引されていません
評価
この issue はまだ評価されていません。