From 36168ab68ba9f02c844874d942acf20ee0da66de Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Mon, 25 Oct 2021 16:53:50 +0200 Subject: [PATCH 01/10] Add API token documentation --- .../database-apis-reference/rest-api.md | 10 +++++++++- .../configurations/optional/api-tokens.md | 0 .../configurations/optional/environment.md | 3 ++- .../configurations/required/server.md | 20 +++++++++++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 docs/developer-docs/latest/setup-deployment-guides/configurations/optional/api-tokens.md diff --git a/docs/developer-docs/latest/developer-resources/database-apis-reference/rest-api.md b/docs/developer-docs/latest/developer-resources/database-apis-reference/rest-api.md index e9a4465b17..4f0826d475 100644 --- a/docs/developer-docs/latest/developer-resources/database-apis-reference/rest-api.md +++ b/docs/developer-docs/latest/developer-resources/database-apis-reference/rest-api.md @@ -8,7 +8,7 @@ sidebarDepth: 3 The REST API allows accessing the [content-types](/developer-docs/latest/development/backend-customization/models.md#content-types) through API endpoints that Strapi automatically creates. -[API parameters](#api-parameters) can be used to [filter](#filters), [sort](#sorting), and [paginate](#pagination) results and to [select fields](#fields-selection) and relations to [populate](#relations-population). Additionally, specific parameters related to optional Strapi features can be used, like [publication state](#publication-state) and [locale](#locale). +[API parameters](#api-parameters) can be used to [filter](#filters), [sort](#sorting), and [paginate](#pagination) results and to [select fields](#fields-selection) and relations to [populate](#relations-population). Additionally, specific parameters related to optional Strapi features can be used, like [publication state](#publication-state), [locale](#locale), and an [API token](#api-token). ## API Endpoints @@ -684,3 +684,11 @@ To retrieve only draft entries, combine the `preview` publication state and the ::: The `locale` API parameter can be used to [get entries from a specific locale](/developer-docs/latest/plugins/i18n.md#getting-localized-entries-with-the-locale-parameter). + +### API token + +The `api-token` API parameter can be used to authenticate a request by passing an [API token](/developer-docs/latest/setup-deployment-guides/configurations/required/server.md#api-tokens). + +:::request Example request: Get published articles with an API token to authenticate the request +`GET /api/articles?api-token=my-secret-key` +::: diff --git a/docs/developer-docs/latest/setup-deployment-guides/configurations/optional/api-tokens.md b/docs/developer-docs/latest/setup-deployment-guides/configurations/optional/api-tokens.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.md b/docs/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.md index b764267130..e55e9d8a30 100644 --- a/docs/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.md +++ b/docs/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.md @@ -69,7 +69,8 @@ Some settings can only be modified through environment variables: | `NODE_ENV` | String | Type of environment where the app is running | `'development'` | | `BROWSER` | Boolean | Open the admin panel in the browser after startup | `true` | | `ENV_PATH` | String | Path to the file that contains your environment variables | `'./.env'` | -| `STRAPI_PLUGIN_I18N_INIT_LOCALE_CODE` | String | _Optional_

Initialization locale for the app, if the [Internationalization (i18n) plugin](/developer-docs/latest/plugins/i18n.md) is installed and enabled on Content-Types (see [Configuration of i18n in production environments](/developer-docs/latest/plugins/i18n.md#configuration-in-production-environments)) | `'en'` | +| `STRAPI_PLUGIN_I18N_INIT_LOCALE_CODE`

_Optional_| String | Initialization locale for the app, if the [Internationalization (i18n) plugin](/developer-docs/latest/plugins/i18n.md) is installed and enabled on Content-Types (see [Configuration of i18n in production environments](/developer-docs/latest/plugins/i18n.md#configuration-in-production-environments)) | `'en'` | +| `API_TOKEN_SALT`

_Optional_ | String | Salt to use to generate [API tokens](/developer-docs/latest/setup-deployment-guides/configurations/required/server.md#api-tokens) | - | ### Configuration using environment variables diff --git a/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md b/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md index 64dea8758b..99353eadd1 100644 --- a/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md +++ b/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md @@ -100,6 +100,7 @@ module.exports = ({ env }) => ({ | `cron` | Cron configuration (powered by [`node-schedule`](https://github.com/node-schedule/node-schedule)) | Object | | | `cron.enabled` | Enable or disable CRON tasks to schedule jobs at specific dates. | boolean | `false` | | `admin` | Admin panel configuration | Object | | +| `admin.api-tokens.salt` | Salt used to generate [API tokens](#api-tokens) | String | (A random string
generated
by Strapi) | | `admin.auth` | Authentication configuration | Object | | | `admin.auth.secret` | Secret used to encode JWT tokens | string | `undefined` | | `admin.auth.events` | Record of all the events subscribers registered for the authentication | object | `{}` | @@ -115,3 +116,22 @@ module.exports = ({ env }) => ({ | `admin.forgotPassword.emailTemplate` | Email template as defined in [email plugin](/developer-docs/latest/plugins/email.md#programmatic-usage) | Object | [Default template](https://github.com/strapi/strapi/tree/master/packages/strapi-admin/config/email-templates/forgot-password.js) | | `admin.forgotPassword.from` | Sender mail address | string | Default value defined in your [provider configuration](/developer-docs/latest/plugins/email.md#configure-the-plugin) | | `admin.forgotPassword.replyTo` | Default address or addresses the receiver is asked to reply to | string | Default value defined in your [provider configuration](/developer-docs/latest/plugins/email.md#configure-the-plugin) | + +## API tokens + +Authentication strategies in Strapi can either be based on the use of the [Users & Permissions plugin](/user-docs/latest/users-roles-permissions/introduction-to-users-roles-permissions.md) or on the built-in [API token]() feature. + + + +Using API tokens allows executing a request on [REST API](/developer-docs/latest/developer-resources/database-apis-reference/rest-api.md) endpoints as an authenticated user with [the `api-token` parameter](/developer-docs/latest/developer-resources/database-apis-reference/rest-api.md#api-token). + +New API tokens are generated from the admin panel using a salt. This salt is automatically generated by Strapi and stored in `./config/server.js` as `admin.api-tokens.salt`. + +The salt can be customized: + +- either by updating the string value for `admin.api-tokens.salt` in `./config/server.js` +- or by creating an `API_TOKEN_SALT` [environment variable](/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.md#environment-variables) in the `.env` file of the project + +::: caution +Changing the salt invalidates all the existing API tokens . +::: From e599a261034e01d1721b6ac82984fc14c3003193 Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Mon, 25 Oct 2021 17:03:07 +0200 Subject: [PATCH 02/10] Delete file(s) --- .../developer-docs/latest/guides/api-token.md | 99 ------------------- .../configurations/optional/api-tokens.md | 0 2 files changed, 99 deletions(-) delete mode 100644 docs/developer-docs/latest/guides/api-token.md delete mode 100644 docs/developer-docs/latest/setup-deployment-guides/configurations/optional/api-tokens.md diff --git a/docs/developer-docs/latest/guides/api-token.md b/docs/developer-docs/latest/guides/api-token.md deleted file mode 100644 index d3948d9706..0000000000 --- a/docs/developer-docs/latest/guides/api-token.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: API Tokens - Strapi Developer Documentation -description: Learn in this guide how to create an API token system in your Strapi project to execute request as an authenticated user. ---- - -# API tokens - -In this guide we will see how you can create an API token system to execute request as an authenticated user. - -This feature is in our [roadmap](https://portal.productboard.com/strapi/1-public-roadmap/c/40-api-access-token-with-permissions). -This guide is a workaround to achieve this feature before we support it natively in strapi. - -## Introduction - -The goal is to be able to request API endpoints with a query parameter `token` that authenticates as a user. `eg. /restaurants?token=my-secret-token`. - -To achieve this feature in development, we will have to customize the `users-permissions` plugin. This guide will help you understand how to customize all your applications. You can read more about [Strapi plugins and customization](/developer-docs/latest/development/plugins-extension.md). - -## Create the Token Content Type - -To manage your tokens, you will have to create a new Content Type named `token`. - -- `string` attribute named `token` -- `relation` attribute **Token** (`user`) - **Token** has and belongs to one **User** - **User** (`token`) - -Then add some users and create some token linked to these users. - -## Setup the file to override - -We now have to customize the function that verifies the `token` token. Strapi has an Authentication process that uses `JWT` tokens, we will reuse this function to customize the verification. - -[Here is the function](https://github.com/strapi/strapi/blob/master/packages/strapi-plugin-users-permissions/config/policies/permissions.js) that manages the JWT validation. - -To be able to customize it, you will have to create a new file in your application `./extensions/users-permissions/config/policies/permissions.js`. - -Then copy the original function that is on GitHub and paste it in your new file. - -When it's done, the Strapi application will use this function instead of the core one. We are ready to customize it. - -## Add token validation logic - -You will have to update the first lines of this function. - -**Path —** `./extensions/users-permissions/config/policies/permissions.js` - -```js -const _ = require('lodash'); - -module.exports = async (ctx, next) => { - let role; - - if (ctx.state.user) { - // request is already authenticated in a different way - return next(); - } - - // add the detection of `token` query parameter - if ( - (ctx.request && ctx.request.header && ctx.request.header.authorization) || - (ctx.request.query && ctx.request.query.token) - ) { - try { - // init `id` and `isAdmin` outside of validation blocks - let id; - let isAdmin; - - if (ctx.request.query && ctx.request.query.token) { - // find the token entry that match the token from the request - const [token] = await strapi.query('token').find({token: ctx.request.query.token}); - - if (!token) { - throw new Error(`Invalid token: This token doesn't exist`); - } else { - if (token.user && typeof token.token === 'string') { - id = token.user.id; - } - isAdmin = false; - } - - delete ctx.request.query.token; - } else if (ctx.request && ctx.request.header && ctx.request.header.authorization) { - // use the current system with JWT in the header - const decoded = await strapi.plugins[ - 'users-permissions' - ].services.jwt.getToken(ctx); - - id = decoded.id; - isAdmin = decoded.isAdmin || false; - } - - // this is the line that already exist in the code - if (id === undefined) { - throw new Error('Invalid token: Token did not contain required fields'); - } - - ... -``` - -And tada! You can now create a token, link it to a user and use it in your URLs with `token` as query parameters. diff --git a/docs/developer-docs/latest/setup-deployment-guides/configurations/optional/api-tokens.md b/docs/developer-docs/latest/setup-deployment-guides/configurations/optional/api-tokens.md deleted file mode 100644 index e69de29bb2..0000000000 From afd851a9ed043a0d1fa1aded38fa4697fe458e75 Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Mon, 25 Oct 2021 17:46:33 +0200 Subject: [PATCH 03/10] Add example to full server config --- .../setup-deployment-guides/configurations/required/server.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md b/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md index 99353eadd1..40e8f84ac7 100644 --- a/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md +++ b/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md @@ -53,6 +53,9 @@ module.exports = ({ env }) => ({ enabled: env.bool('CRON_ENABLED', false), }, admin: { + api-tokens: { + salt: 'random_string_used_as_a_salt' + }, auth: { events: { onConnectionSuccess(e) { From 4c0193bbf877991ce98d276f5d8c2f46c7c96e0f Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Wed, 27 Oct 2021 14:35:04 +0200 Subject: [PATCH 04/10] Revert changes to REST API API token is passed in the header --- .../database-apis-reference/rest-api.md | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/docs/developer-docs/latest/developer-resources/database-apis-reference/rest-api.md b/docs/developer-docs/latest/developer-resources/database-apis-reference/rest-api.md index 4f0826d475..e9a4465b17 100644 --- a/docs/developer-docs/latest/developer-resources/database-apis-reference/rest-api.md +++ b/docs/developer-docs/latest/developer-resources/database-apis-reference/rest-api.md @@ -8,7 +8,7 @@ sidebarDepth: 3 The REST API allows accessing the [content-types](/developer-docs/latest/development/backend-customization/models.md#content-types) through API endpoints that Strapi automatically creates. -[API parameters](#api-parameters) can be used to [filter](#filters), [sort](#sorting), and [paginate](#pagination) results and to [select fields](#fields-selection) and relations to [populate](#relations-population). Additionally, specific parameters related to optional Strapi features can be used, like [publication state](#publication-state), [locale](#locale), and an [API token](#api-token). +[API parameters](#api-parameters) can be used to [filter](#filters), [sort](#sorting), and [paginate](#pagination) results and to [select fields](#fields-selection) and relations to [populate](#relations-population). Additionally, specific parameters related to optional Strapi features can be used, like [publication state](#publication-state) and [locale](#locale). ## API Endpoints @@ -684,11 +684,3 @@ To retrieve only draft entries, combine the `preview` publication state and the ::: The `locale` API parameter can be used to [get entries from a specific locale](/developer-docs/latest/plugins/i18n.md#getting-localized-entries-with-the-locale-parameter). - -### API token - -The `api-token` API parameter can be used to authenticate a request by passing an [API token](/developer-docs/latest/setup-deployment-guides/configurations/required/server.md#api-tokens). - -:::request Example request: Get published articles with an API token to authenticate the request -`GET /api/articles?api-token=my-secret-key` -::: From 6b3e56c4c71d7b30d959f0d762af4196e2b2fc44 Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Wed, 27 Oct 2021 14:40:02 +0200 Subject: [PATCH 05/10] Update how the API token is passed along with the request --- .../setup-deployment-guides/configurations/required/server.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md b/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md index 40e8f84ac7..2c9bf26c0a 100644 --- a/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md +++ b/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md @@ -126,7 +126,7 @@ Authentication strategies in Strapi can either be based on the use of the [Users -Using API tokens allows executing a request on [REST API](/developer-docs/latest/developer-resources/database-apis-reference/rest-api.md) endpoints as an authenticated user with [the `api-token` parameter](/developer-docs/latest/developer-resources/database-apis-reference/rest-api.md#api-token). +Using API tokens allows executing a request on [REST API](/developer-docs/latest/developer-resources/database-apis-reference/rest-api.md) endpoints as an authenticated user. The API token should be added to the request's `Authorization` header with the following syntax: `bearer your-api-token`. New API tokens are generated from the admin panel using a salt. This salt is automatically generated by Strapi and stored in `./config/server.js` as `admin.api-tokens.salt`. From 04a7d1c07cccb4f870f71e2b22e126f433e07f9a Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Wed, 27 Oct 2021 14:40:10 +0200 Subject: [PATCH 06/10] Fix typo: unneeded space --- .../setup-deployment-guides/configurations/required/server.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md b/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md index 2c9bf26c0a..10e193f8de 100644 --- a/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md +++ b/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md @@ -136,5 +136,5 @@ The salt can be customized: - or by creating an `API_TOKEN_SALT` [environment variable](/developer-docs/latest/setup-deployment-guides/configurations/optional/environment.md#environment-variables) in the `.env` file of the project ::: caution -Changing the salt invalidates all the existing API tokens . +Changing the salt invalidates all the existing API tokens. ::: From 5d5e95104eac2d5cc31895c2a070b78cf44f73a9 Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Wed, 27 Oct 2021 16:26:58 +0200 Subject: [PATCH 07/10] `apiToken`: camelCase + move to minimal config (Note: will be moved to ./config/admin.js in another PR) --- .../configurations/required/server.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md b/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md index 10e193f8de..2297bdc476 100644 --- a/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md +++ b/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md @@ -24,6 +24,9 @@ module.exports = ({ env }) => ({ host: env('HOST', '0.0.0.0'), port: env.int('PORT', 1337), admin: { + apiToken: { + salt: 'random_string_used_as_a_salt' + }, auth: { secret: env('ADMIN_JWT_SECRET', 'someSecretKey'), }, @@ -53,7 +56,7 @@ module.exports = ({ env }) => ({ enabled: env.bool('CRON_ENABLED', false), }, admin: { - api-tokens: { + apiToken: { salt: 'random_string_used_as_a_salt' }, auth: { From 743d442a06939e9197c1ddc03a5b91a18b0d0eca Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Tue, 2 Nov 2021 16:01:09 +0100 Subject: [PATCH 08/10] Update docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md Co-authored-by: DMehaffy --- .../setup-deployment-guides/configurations/required/server.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md b/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md index 2297bdc476..d471c9b8c5 100644 --- a/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md +++ b/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md @@ -25,7 +25,7 @@ module.exports = ({ env }) => ({ port: env.int('PORT', 1337), admin: { apiToken: { - salt: 'random_string_used_as_a_salt' + salt: env('API_TOKEN_SALT','random_string_used_as_a_salt'), }, auth: { secret: env('ADMIN_JWT_SECRET', 'someSecretKey'), From 367a036beff3d285350d7e0f255aeddf2759cd78 Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Tue, 2 Nov 2021 16:01:16 +0100 Subject: [PATCH 09/10] Update docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md Co-authored-by: DMehaffy --- .../setup-deployment-guides/configurations/required/server.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md b/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md index d471c9b8c5..21addd5d3f 100644 --- a/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md +++ b/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md @@ -57,7 +57,7 @@ module.exports = ({ env }) => ({ }, admin: { apiToken: { - salt: 'random_string_used_as_a_salt' + salt: env('API_TOKEN_SALT','random_string_used_as_a_salt'), }, auth: { events: { From ddd4def7064698ec04973fdbfb987dcdaf0d98d7 Mon Sep 17 00:00:00 2001 From: Pierre Wizla Date: Tue, 2 Nov 2021 16:04:55 +0100 Subject: [PATCH 10/10] Update docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md --- .../setup-deployment-guides/configurations/required/server.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md b/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md index 21addd5d3f..5d31e37770 100644 --- a/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md +++ b/docs/developer-docs/latest/setup-deployment-guides/configurations/required/server.md @@ -106,7 +106,7 @@ module.exports = ({ env }) => ({ | `cron` | Cron configuration (powered by [`node-schedule`](https://github.com/node-schedule/node-schedule)) | Object | | | `cron.enabled` | Enable or disable CRON tasks to schedule jobs at specific dates. | boolean | `false` | | `admin` | Admin panel configuration | Object | | -| `admin.api-tokens.salt` | Salt used to generate [API tokens](#api-tokens) | String | (A random string
generated
by Strapi) | +| `admin.apiToken.salt` | Salt used to generate [API tokens](#api-tokens) | String | (A random string
generated
by Strapi) | | `admin.auth` | Authentication configuration | Object | | | `admin.auth.secret` | Secret used to encode JWT tokens | string | `undefined` | | `admin.auth.events` | Record of all the events subscribers registered for the authentication | object | `{}` |