From 79c91ed50dc7a6324c3ffe37c340442dec09a65b Mon Sep 17 00:00:00 2001 From: j3n57h0m45 <77627854+j3n57h0m45@users.noreply.github.com> Date: Tue, 20 Jul 2021 15:29:11 +0200 Subject: [PATCH] enable custom name for refresh token (#6890) --- api/example.env | 1 + api/src/cli/utils/create-env/env-stub.liquid | 1 + api/src/controllers/auth.ts | 14 +++++++------- api/src/env.ts | 1 + api/src/logger.ts | 2 +- api/src/services/graphql.ts | 8 ++++---- docs/reference/environment-variables.md | 3 ++- 7 files changed, 17 insertions(+), 13 deletions(-) diff --git a/api/example.env b/api/example.env index 9249c9483c..9ca6f4b637 100644 --- a/api/example.env +++ b/api/example.env @@ -103,6 +103,7 @@ ACCESS_TOKEN_TTL="15m" REFRESH_TOKEN_TTL="7d" REFRESH_TOKEN_COOKIE_SECURE="false" REFRESH_TOKEN_COOKIE_SAME_SITE="lax" +REFRESH_TOKEN_COOKIE_NAME="directus_refresh_token" CORS_ENABLED="true" CORS_ORIGIN="true" diff --git a/api/src/cli/utils/create-env/env-stub.liquid b/api/src/cli/utils/create-env/env-stub.liquid index 21ca7e197b..d381a60185 100644 --- a/api/src/cli/utils/create-env/env-stub.liquid +++ b/api/src/cli/utils/create-env/env-stub.liquid @@ -38,6 +38,7 @@ ACCESS_TOKEN_TTL="15m" REFRESH_TOKEN_TTL="7d" REFRESH_TOKEN_COOKIE_SECURE=false REFRESH_TOKEN_COOKIE_SAME_SITE="lax" +REFRESH_TOKEN_COOKIE_NAME="directus_refresh_token" #################################################################################################### ## SSO (OAuth) Providers diff --git a/api/src/controllers/auth.ts b/api/src/controllers/auth.ts index 997177e583..b1342c940c 100644 --- a/api/src/controllers/auth.ts +++ b/api/src/controllers/auth.ts @@ -59,7 +59,7 @@ router.post( } if (mode === 'cookie') { - res.cookie('directus_refresh_token', refreshToken, { + res.cookie(env.REFRESH_TOKEN_COOKIE_NAME, refreshToken, { httpOnly: true, domain: env.REFRESH_TOKEN_COOKIE_DOMAIN, maxAge: ms(env.REFRESH_TOKEN_TTL as string), @@ -88,7 +88,7 @@ router.post( schema: req.schema, }); - const currentRefreshToken = req.body.refresh_token || req.cookies.directus_refresh_token; + const currentRefreshToken = req.body.refresh_token || req.cookies[env.REFRESH_TOKEN_COOKIE_NAME]; if (!currentRefreshToken) { throw new InvalidPayloadException(`"refresh_token" is required in either the JSON payload or Cookie`); @@ -107,7 +107,7 @@ router.post( } if (mode === 'cookie') { - res.cookie('directus_refresh_token', refreshToken, { + res.cookie(env.REFRESH_TOKEN_COOKIE_NAME, refreshToken, { httpOnly: true, domain: env.REFRESH_TOKEN_COOKIE_DOMAIN, maxAge: ms(env.REFRESH_TOKEN_TTL as string), @@ -136,7 +136,7 @@ router.post( schema: req.schema, }); - const currentRefreshToken = req.body.refresh_token || req.cookies.directus_refresh_token; + const currentRefreshToken = req.body.refresh_token || req.cookies[env.REFRESH_TOKEN_COOKIE_NAME]; if (!currentRefreshToken) { throw new InvalidPayloadException(`"refresh_token" is required in either the JSON payload or Cookie`); @@ -144,8 +144,8 @@ router.post( await authenticationService.logout(currentRefreshToken); - if (req.cookies.directus_refresh_token) { - res.clearCookie('directus_refresh_token', { + if (req.cookies[env.REFRESH_TOKEN_COOKIE_NAME]) { + res.clearCookie(env.REFRESH_TOKEN_COOKIE_NAME, { httpOnly: true, domain: env.REFRESH_TOKEN_COOKIE_DOMAIN, secure: env.REFRESH_TOKEN_COOKIE_SECURE ?? false, @@ -340,7 +340,7 @@ router.get( emitStatus('success'); if (redirect) { - res.cookie('directus_refresh_token', refreshToken, { + res.cookie(env.REFRESH_TOKEN_COOKIE_NAME, refreshToken, { httpOnly: true, domain: env.REFRESH_TOKEN_COOKIE_DOMAIN, maxAge: ms(env.REFRESH_TOKEN_TTL as string), diff --git a/api/src/env.ts b/api/src/env.ts index b97c3dca00..40295d36dd 100644 --- a/api/src/env.ts +++ b/api/src/env.ts @@ -34,6 +34,7 @@ const defaults: Record = { REFRESH_TOKEN_TTL: '7d', REFRESH_TOKEN_COOKIE_SECURE: false, REFRESH_TOKEN_COOKIE_SAME_SITE: 'lax', + REFRESH_TOKEN_COOKIE_NAME: 'directus_refresh_token', ROOT_REDIRECT: './admin', diff --git a/api/src/logger.ts b/api/src/logger.ts index d03bd7aa2d..42d64916a3 100644 --- a/api/src/logger.ts +++ b/api/src/logger.ts @@ -7,7 +7,7 @@ import env from './env'; const pinoOptions: LoggerOptions = { level: env.LOG_LEVEL || 'info', redact: { - paths: ['req.headers.authorization', 'req.cookies.directus_refresh_token'], + paths: ['req.headers.authorization', `req.cookies.${env.REFRESH_TOKEN_COOKIE_NAME}`], censor: '--redact--', }, }; diff --git a/api/src/services/graphql.ts b/api/src/services/graphql.ts index ca297efffd..2947caf770 100644 --- a/api/src/services/graphql.ts +++ b/api/src/services/graphql.ts @@ -1376,7 +1376,7 @@ export class GraphQLService { userAgent: req?.get('user-agent'), }); if (args.mode === 'cookie') { - res?.cookie('directus_refresh_token', result.refreshToken, { + res?.cookie(env.REFRESH_TOKEN_COOKIE_NAME, result.refreshToken, { httpOnly: true, domain: env.REFRESH_TOKEN_COOKIE_DOMAIN, maxAge: ms(env.REFRESH_TOKEN_TTL as string), @@ -1407,13 +1407,13 @@ export class GraphQLService { accountability: accountability, schema: this.schema, }); - const currentRefreshToken = args.refresh_token || req?.cookies.directus_refresh_token; + const currentRefreshToken = args.refresh_token || req?.cookies[env.REFRESH_TOKEN_COOKIE_NAME]; if (!currentRefreshToken) { throw new InvalidPayloadException(`"refresh_token" is required in either the JSON payload or Cookie`); } const result = await authenticationService.refresh(currentRefreshToken); if (args.mode === 'cookie') { - res?.cookie('directus_refresh_token', result.refreshToken, { + res?.cookie(env.REFRESH_TOKEN_COOKIE_NAME, result.refreshToken, { httpOnly: true, domain: env.REFRESH_TOKEN_COOKIE_DOMAIN, maxAge: ms(env.REFRESH_TOKEN_TTL as string), @@ -1443,7 +1443,7 @@ export class GraphQLService { accountability: accountability, schema: this.schema, }); - const currentRefreshToken = args.refresh_token || req?.cookies.directus_refresh_token; + const currentRefreshToken = args.refresh_token || req?.cookies[env.REFRESH_TOKEN_COOKIE_NAME]; if (!currentRefreshToken) { throw new InvalidPayloadException(`"refresh_token" is required in either the JSON payload or Cookie`); } diff --git a/docs/reference/environment-variables.md b/docs/reference/environment-variables.md index 0cc3ef9dea..06eb7b777e 100644 --- a/docs/reference/environment-variables.md +++ b/docs/reference/environment-variables.md @@ -60,13 +60,14 @@ All the `DB_POOL_` prefixed options are passed [to `tarn.js`](https://github.com | `REFRESH_TOKEN_COOKIE_DOMAIN` | Which domain to use for the refresh cookie. Useful for development mode. | -- | | `REFRESH_TOKEN_COOKIE_SECURE` | Whether or not to use a secure cookie for the refresh token in cookie mode. | `false` | | `REFRESH_TOKEN_COOKIE_SAME_SITE` | Value for `sameSite` in the refresh token cookie when in cookie mode. | `lax` | +| `REFRESH_TOKEN_COOKIE_NAME` | Name of refresh token cookie . | `directus_refresh_token`| | `PASSWORD_RESET_URL_ALLOW_LIST` | List of URLs that can be used [as `reset_url` in /password/request](/reference/api/system/authentication/#request-password-reset) | -- | | `USER_INVITE_URL_ALLOW_LIST` | List of URLs that can be used [as `invite_url` in /users/invite](/reference/api/system/users/#invite-a-new-user) | -- | ::: tip Cookie Strictness Browser are pretty strict when it comes to third-party cookies. If you're running into unexpected problems when running -your project and API on different domains, make sure to verify your configuration for `REFRESH_TOKEN_COOKIE_SECURE` and +your project and API on different domains, make sure to verify your configuration for `REFRESH_TOKEN_COOKIE_NAME`, `REFRESH_TOKEN_COOKIE_SECURE` and `REFRESH_TOKEN_COOKIE_SAME_SITE`. :::