You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Document that OAuth providers belong under authentication.oauth and
must not be listed in public authStrategies for browser redirect SSO.
Rewrite flow #2 guidance so provider-token login requires a verifying
getProfile, and cross-link guides and cookbooks.
Copy file name to clipboardExpand all lines: docs/api/authentication/oauth.md
+74-9Lines changed: 74 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -56,6 +56,55 @@ The following settings for `app.configure(oauth())` are available:
56
56
-`expressSession` - An Express middleware for handling sessions. By default will use an HTTP cookie that is only available for the oAuth flow. **This normally does not need to be changed.**
57
57
-`koaSession` - A Koa middleware for handling sessions. By default will use an HTTP cookie that is only available for the oAuth flow. **This normally does not need to be changed.**
58
58
59
+
### Configuration and security
60
+
61
+
OAuth setup uses three separate pieces. Only the first two are required for the usual browser redirect login:
62
+
63
+
| Piece | Role |
64
+
| --- | --- |
65
+
|`authentication.register('google', new OAuthStrategy())`| Registers the strategy so the OAuth callback can run it |
66
+
|`authentication.oauth.google` in configuration | Grant provider options (`key`, `secret`, `scope`, …) |
67
+
|`authentication.authStrategies`| Strategy names clients may use on **external**`POST /authentication`|
68
+
69
+
Browser redirect SSO (`/oauth/<provider>`) only needs **register** + **`authentication.oauth`**. The OAuth callback allows that provider for the internal authentication call after Grant finishes. Provider names do **not** need to be listed in public [`authStrategies`](./service.md#configuration).
70
+
71
+
The [Feathers generator](../../guides/cli/authentication.md) already follows this pattern: OAuth providers are configured under `authentication.oauth`, while `authStrategies` typically stays `["jwt", "local"]`.
72
+
73
+
```json
74
+
// Typical safe config for browser-only OAuth (matches the generator)
75
+
{
76
+
"authentication": {
77
+
"authStrategies": ["jwt", "local"],
78
+
"oauth": {
79
+
"google": {
80
+
"key": "<Client ID>",
81
+
"secret": "<Client secret>"
82
+
}
83
+
}
84
+
}
85
+
}
86
+
```
87
+
88
+
```json
89
+
// Unsafe for the default OAuthStrategy when you only need browser SSO.
90
+
// Do not list provider names here unless you implement verified token login (flow #2).
Putting an OAuth provider name (for example `google` or `github`) in [`authStrategies`](./service.md#configuration) exposes that strategy on external `POST /authentication`.
101
+
102
+
The default [`getProfile`](#getprofile-data-params) implementation returns `data.profile` from the authentication payload. That is safe when the payload is built **server-side** by the OAuth callback after Grant. It is **not** safe to accept a client-supplied `profile` (for example `{ strategy: 'google', profile: { sub: '...' } }`) as proof of identity. A provider `sub` or `id` is an identifier, not a credential.
103
+
104
+
Only add a provider to `authStrategies` when you intentionally support [flow #2](#flow) (existing provider access token) **and** override `getProfile` to verify that token with the provider. See the [Facebook](../../cookbook/authentication/facebook.md) and [Firebase](../../cookbook/authentication/firebase.md) cookbooks for verified-token patterns.
105
+
106
+
</BlockQuote>
107
+
59
108
### Providers
60
109
61
110
For specific OAuth provider setup see the following [cookbook](../../cookbook/) guides:
@@ -73,22 +122,29 @@ There are two ways to initiate OAuth authentication:
73
122
- User clicks on link to OAuth URL (`oauth/<provider>`)
74
123
- Gets redirected to provider and authorizes the application
75
124
- Callback to the [OauthStrategy](#oauthstrategy) which
76
-
- Gets the users profile
125
+
- Gets the users profile (from the server-side Grant response)
77
126
- Finds or creates the user (entity) for that profile
78
127
- The [AuthenticationService](./service.md) creates an access token for that entity
79
128
- Redirects back to the origin URL including the generated access token
80
129
- The frontend (e.g. the Feathers [authentication client](./client.md)) uses the returned access token to authenticate
81
130
82
-
2. With an existing access token, e.g. obtained through the Facebook mobile SDK
83
-
- Authenticate normally through the [authentication service](./service.md) with `{ strategy: '<name>', accessToken: 'oauth access token' }`.
84
-
- Calls the [OauthStrategy](#oauthstrategy) which
85
-
- Gets the users profile
86
-
- Finds or creates the entity for that profile
131
+
This flow does **not** require the provider name in [`authStrategies`](./service.md#configuration). See [Configuration and security](#configuration-and-security).
132
+
133
+
2. With an existing provider access token (for example from a mobile SDK)
134
+
135
+
- Authenticate through the [authentication service](./service.md) with a request like `{ strategy: '<name>', accessToken: '<provider access token>' }` (some providers use `access_token` or an ID token instead).
136
+
- The strategy must obtain the user profile by **verifying that token with the provider** (userinfo endpoint, Graph API, ID token verification, and so on).
137
+
- Finds or creates the entity for that profile
87
138
- Returns the authentication result
88
139
89
140
<BlockQuotetype="warning"label="Important">
90
141
91
-
If you are attempting to authenticate using an existing oAuth access token, ensure that you have added the strategy (e.g. 'facebook') to the allowed [authStrategies](./service.md#configuration) configuration.
142
+
Flow #2 needs **both** of the following:
143
+
144
+
1. The strategy name (for example `'facebook'`) in the allowed [`authStrategies`](./service.md#configuration) configuration so clients can call `POST /authentication`.
145
+
2. An overridden [`getProfile`](#getprofile-data-params) that derives identity only from a **verified** provider response. Do not trust a client-supplied `profile` or `sub`.
146
+
147
+
The default `OAuthStrategy` does not call the provider when given only a client `profile`. Without a verifying `getProfile`, listing the provider in `authStrategies` is a serious security misconfiguration. See the [Facebook](../../cookbook/authentication/facebook.md) cookbook (Graph API with the access token) and the [Firebase](../../cookbook/authentication/firebase.md) cookbook (`verifyIdToken`) for correct patterns.
92
148
93
149
</BlockQuote>
94
150
@@ -254,9 +310,15 @@ Here is a [list of all Grant configuration options](https://github.com/simov/gra
254
310
255
311
`oauthStrategy.getEntityData(profile, existing, params) -> Promise` returns the data to either create a new or update an existing entity. `entity` is either the existing entity or `null` when creating a new entity.
256
312
313
+
By default this only sets the provider id field (for example `googleId`). Custom strategies often also copy `email` or avatar fields from the profile. Prefer setting sensitive identity fields such as email when **creating** a user, or through an authenticated account-linking step. Avoid blindly rewriting recovery email on every login from profile data.
314
+
257
315
### getProfile(data, params)
258
316
259
-
`oauthStrategy.getProfile(data, params) -> Promise` returns the user profile information from the OAuth provider that was used for the login. `data` is the OAuth callback information which normally contains e.g. the OAuth access token.
317
+
`oauthStrategy.getProfile(data, params) -> Promise` returns the user profile used for the login.
318
+
319
+
**Default behavior:** returns `data.profile` from the authentication payload. In the browser redirect flow that profile is set **server-side** by the OAuth callback after Grant completes. The default method does **not** call the provider itself.
320
+
321
+
When authenticating with a client-held provider token ([flow #2](#flow)), override `getProfile` to verify the token with the provider and build the profile from that verified response. Never treat a client-supplied `profile` as verified identity.
Copy file name to clipboardExpand all lines: docs/api/authentication/service.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -63,7 +63,7 @@ The following options are available:
63
63
64
64
-`secret`: The JWT signing secret.
65
65
-`service`: The path of the entity service
66
-
-`authStrategies`: A list of authentication strategy names to allow on this authenticationservice to create access tokens.
66
+
-`authStrategies`: A list of authentication strategy names allowed for **external**`create` calls (`POST /authentication` / `app.service('authentication').create`). Typical values are `jwt`, `local`, API keys, and only those custom strategies that accept external credentials. [OAuth](./oauth.md) providers used solely via the `/oauth/<provider>` redirect flow should be [registered](#register-name-strategy) and configured under `authentication.oauth`, but are usually **omitted** from this list. See [OAuth configuration and security](./oauth.md#configuration-and-security).
67
67
-`parseStrategies`: A list of authentication strategies that should be used to parse HTTP requests. Defaults to the same as `authStrategies`.
68
68
-`entity`: The name of the field that will contain the entity after successful authentication. Will also be used to set `params[entity]` (usually `params.user`) when using the [authenticate hook](./hook). Can be `null` if no entity is used (see [stateless tokens](../../cookbook/authentication/stateless.md)).
69
69
-`entityId`: The id property of an entity object. Only necessary if the entity service does not have an `id` property (e.g. when using a custom entity service).
@@ -95,7 +95,7 @@ An authentication service configuration in `config/default.json` can look like t
95
95
96
96
</BlockQuote>
97
97
98
-
Additionally to the above configuration, most [strategies](./strategy.md) will look for their own configuration under the name it was registered. An example can be found in the [local strategy configuration](./local.md#configuration).
98
+
Additionally to the above configuration, most [strategies](./strategy.md) will look for their own configuration under the name it was registered. An example can be found in the [local strategy configuration](./local.md#configuration). OAuth provider settings live under `authentication.oauth` (see [OAuth options](./oauth.md#options)), which is separate from `authStrategies`.
Copy file name to clipboardExpand all lines: docs/cookbook/authentication/facebook.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -44,6 +44,8 @@ The client id (App ID) and secret can be found in the Settings of the [Facebook
44
44
45
45
The standard OAuth strategy only returns the default profile fields (`id` and `name`). To get other fields, like the email or profile picture, the [getProfile](../../api/authentication/oauth.md#getprofile-data-params) method of the [OAuth strategy needs to be customized](../../api/authentication/oauth.md#customization) to call the Graph API profile endpoint `https://graph.facebook.com/me` with an HTTP request library like [Axios](https://developers.facebook.com/tools/explorer/) requesting the additional fields.
46
46
47
+
This `getProfile` pattern (call Graph with the provider access token) is also **required** if you put `"facebook"` in [`authStrategies`](../../api/authentication/service.md#configuration) so clients can authenticate with `{ strategy: 'facebook', accessToken: '...' }` on `POST /authentication`. Never accept a client-supplied `profile` as identity. Browser-only Facebook login via `/oauth/facebook` does not need the provider in `authStrategies`. See [OAuth configuration and security](../../api/authentication/oauth.md#configuration-and-security).
48
+
47
49
> __Pro tip:__ Facebook API requests can be tested via the [Graph API explorer](https://developers.facebook.com/tools/explorer/).
48
50
49
51
The following example allows to log in with Facebook in the [chat application from the guide](../../guides/index.md):
Copy file name to clipboardExpand all lines: docs/cookbook/authentication/firebase.md
+3Lines changed: 3 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,6 +16,7 @@ Update `config/default.json`:
16
16
```json
17
17
{
18
18
"authentication": {
19
+
"authStrategies": ["jwt", "firebase"],
19
20
"oauth": {}
20
21
},
21
22
"firebase": {
@@ -28,6 +29,8 @@ Update `config/default.json`:
28
29
```
29
30
> Note: Since Firebase can be used for more than just authentication, we'll store our service account in the root of our config. Otherwise, if preferred, you can store under `authentication.oauth`.
30
31
32
+
`"firebase"` must be listed in `authStrategies` because clients authenticate with `POST /authentication` (flow #2). That is only safe because `getProfile` below calls `verifyIdToken` — never trust a client-supplied profile. See [OAuth configuration and security](../../api/authentication/oauth.md#configuration-and-security).
Copy file name to clipboardExpand all lines: docs/cookbook/authentication/google.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -111,4 +111,6 @@ module.exports = app => {
111
111
```
112
112
**Important**: googleId, profilePicture and email are properties that should exist on the database model!
113
113
114
+
Browser Google login uses `/oauth/google`. You do **not** need to add `"google"` to `authentication.authStrategies` for that redirect flow. Only add it if you implement verified provider-token login on `POST /authentication` — see [OAuth configuration and security](../../api/authentication/oauth.md#configuration-and-security).
For more information about the OAuth flow and strategy see the [OAuth API documentation](../../api/authentication/oauth.md).
242
+
For more information about the OAuth flow and strategy see the [OAuth API documentation](../../api/authentication/oauth.md). Generated apps keep OAuth providers under `authentication.oauth` and **out** of public `authStrategies` on purpose so browser login uses `/oauth/github` only. See [OAuth configuration and security](../../api/authentication/oauth.md#configuration-and-security).
Note that when selecting oAuth logins (Google, Facebook, GitHub etc.), the standard registered oAuth strategy only uses the `<name>Id` property to create a new user. This will fail validation against the default user [schema](./service.schemas.md) which requires an `email` property to exist. If the provider (and user) allows fetching the email, you can customize the oAuth strategy like shown for GitHub in the [oAuth authentication guide](../basics/authentication.md#login-with-github). You can also make the email in the schema optional with `email: Type.Optional(Type.String())`.
33
+
When you select oAuth logins (Google, Facebook, GitHub etc.), the generator registers each provider strategy and adds it under `authentication.oauth` in configuration. Provider names are **not** added to `authentication.authStrategies` — browser SSO uses `/oauth/<provider>` instead of `POST /authentication`. See [OAuth configuration and security](../../api/authentication/oauth.md#configuration-and-security).
34
+
35
+
Note that the standard registered oAuth strategy only uses the `<name>Id` property to create a new user. This will fail validation against the default user [schema](./service.schemas.md) which requires an `email` property to exist. If the provider (and user) allows fetching the email, you can customize the oAuth strategy like shown for GitHub in the [oAuth authentication guide](../basics/authentication.md#login-with-github). You can also make the email in the schema optional with `email: Type.Optional(Type.String())`.
Copy file name to clipboardExpand all lines: docs/guides/cli/default.json.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -53,7 +53,7 @@ These options are used directly in the generated application
53
53
54
54
### authentication
55
55
56
-
`authentication` contains the configuration for the authentication service and strategies. See the [authentication service configuration](../../api/authentication/service.md#configuration) for more information. For strategy specific settings refer to the [jwt](../../api/authentication/jwt.md#options), [local](../../api/authentication/local.md#options) and [oAuth](../../api/authentication/oauth.md#options) API documentation.
56
+
`authentication` contains the configuration for the authentication service and strategies. See the [authentication service configuration](../../api/authentication/service.md#configuration) for more information. For strategy specific settings refer to the [jwt](../../api/authentication/jwt.md#options), [local](../../api/authentication/local.md#options) and [oAuth](../../api/authentication/oauth.md#options) API documentation.`authStrategies` lists strategies allowed on external `POST /authentication` (usually `jwt` and `local`). OAuth provider keys live under `authentication.oauth` and are separate from that list — see [OAuth configuration and security](../../api/authentication/oauth.md#configuration-and-security).
Copy file name to clipboardExpand all lines: docs/guides/security.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -23,6 +23,7 @@ Here are some things that you should be aware of when writing your app to make s
23
23
- Escape any SQL (typically done by the SQL library) to avoid SQL injection.
24
24
- JSON Web Tokens (JWT's) are only signed. They are **not** encrypted. Therefore, the payload can be examined on the client. This is by design. **DO NOT** put anything that should be private in the JWT `payload` unless you encrypt it first.
25
25
- Don't use a weak `secret` for your token service. The generator creates a strong one for you automatically. No need to change it.
26
+
-**OAuth / SSO:** Prefer the browser [redirect flow](../api/authentication/oauth.md#flow) (`/oauth/<provider>`). Register OAuth strategies and configure them under `authentication.oauth`, but do **not** put provider names in [`authStrategies`](../api/authentication/service.md#configuration) unless you intentionally support direct provider-token login **and** verify those tokens in `getProfile`. Never treat a client-supplied provider `profile` or `sub` as proof of identity. Details: [OAuth configuration and security](../api/authentication/oauth.md#configuration-and-security).
0 commit comments