From c236b704b2770678f9c555743877202cc53ecb9a Mon Sep 17 00:00:00 2001 From: Stuart Clark Date: Thu, 20 Aug 2026 06:25:47 +0000 Subject: [PATCH] docs: document Simple OAuth 6 requirements and fix the module example Fixes #35. Investigating the quickstart login failure showed the empty `scope` this module sends is not the bug: Simple OAuth 6 rejects every authorization request - with or without a scope parameter - when no OAuth2 scope exists that the request can resolve, and it ships without any. With a scope created and set as the consumer's authorization code scopes default, the empty `scope=` this module sends is accepted as is, so no code change is needed here. The README now covers what Simple OAuth 6 actually requires: creating a scope, the consumer's Client ID field (lookups use it, not the UUID), and the grant types and scope defaults on the consumer - each of which fails login in its own way when missing. The example also moves the module from buildModules to modules: buildModules are not loaded by `nuxt start`, so the authentication endpoints and proxy this module registers silently vanish in production while the dev server looks fine. --- README.md | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 9f6ebd5..b3b97cb 100644 --- a/README.md +++ b/README.md @@ -23,12 +23,11 @@ Add module to `nuxt.config.js` ```js module.exports = { - buildModules: [ + modules: [ 'druxt', ['druxt-auth', { - clientId: '[DRUPAL_CONSUMER_UUID]', + clientId: '[DRUPAL_CONSUMER_CLIENT_ID]', clientSecret: '[DRUPAL_CONSUMER_SECRET]', - scope: ['default'], }] ], druxt: { @@ -37,17 +36,40 @@ module.exports = { } ``` -_Note:_ Replace `[DRUPAL_CONSUMER_UUID]` and `[DRUPAL_CONSUMER_SECRET]` with the details from the consumer created in the following step. +_Note:_ Use `modules`, not `buildModules`: this module registers the +authentication endpoints and proxy at runtime, and `buildModules` are not +loaded by `nuxt start`, so authentication would silently stop working in +production while the dev server looks fine. + +_Note:_ Replace `[DRUPAL_CONSUMER_CLIENT_ID]` and `[DRUPAL_CONSUMER_SECRET]` with the details from the consumer created in the following step. With Simple OAuth 6 this is the consumer's **Client ID** field, not its UUID. ### Drupal 1. Download, install and setup the [Simple OAuth module](https://www.drupal.org/project/simple_oauth). -2. Create a Consumer depending on your desired authorization strategy: + +2. **Simple OAuth 6.x only:** create an OAuth2 scope + (`/admin/config/people/simple_oauth/oauth2_scope/dynamic`). Simple OAuth 6 + ships without any scopes, and it rejects every authorization request - + with or without a `scope` parameter - until one exists that the request + can resolve: + + - Grant types: enable at least **Authorization code** + - Granularity: e.g. **Role** with the `authenticated` role + +3. Create a Consumer depending on your desired authorization strategy: - **Authorization Code** grant: + - Client ID: _a unique ID of your choosing - this is the `clientId` + the frontend sends (Simple OAuth 6 looks consumers up by this + field, not by UUID)_ - New Secret: _leave this empty_ - Is Confidential: _unchecked_ - Use PKCE?: _checked_ + - Grant types: _enable **Authorization code** (and **Refresh token** + for session renewal)_ + - Authorization code scopes: _the scope from the previous step. This + is the default when the frontend sends no scope of its own, which + is what DruxtAuth does unless the `scope` option is set_ - Redirect URI: `[FRONTEND_URL]/callback` (e.g., `http://localhost:3000/callback`) - **Password** grant: @@ -87,4 +109,4 @@ It adds two auth strategies that can be used via the `$auth` plugin: | --- | --- | --- | --- | --- | | `clientId` | `string` | Yes | `undefined` | The Drupal Consumer UUID | | `clientSecret` | `string` | No | `undefined` | The Drupal Consumer API secret. Required for Password grant. | -| `scope` | `array` | No | `undefined` | The OAuth Scopes to be used for the Drupal Consumer. | +| `scope` | `array` | No | `undefined` | The OAuth scopes to request. When unset, the request carries an empty `scope` and Simple OAuth 6 falls back to the consumer's own **Authorization code scopes** - so either set this option or configure scopes on the consumer. |