diff --git a/website/docs/using-unleash/deploy/getting-started.md b/website/docs/using-unleash/deploy/getting-started.md index 89326783f84f..387e6a8b5301 100644 --- a/website/docs/using-unleash/deploy/getting-started.md +++ b/website/docs/using-unleash/deploy/getting-started.md @@ -26,7 +26,7 @@ Unleash started on http://localhost:4242 To run multiple replicas of Unleash simply point all instances to the same database. -**Unleash v4:** The first time Unleash starts it will create a default user which you can use to sign-in to you Unleash instance and add more users with: +The first time Unleash starts it will create a default user which you can use to sign-in to you Unleash instance and add more users with: - username: `admin` - password: `unleash4all` diff --git a/website/docs/using-unleash/deploy/google-auth-hook.md b/website/docs/using-unleash/deploy/google-auth-hook.md index 07a5137c5c7f..e4bfc0a74043 100644 --- a/website/docs/using-unleash/deploy/google-auth-hook.md +++ b/website/docs/using-unleash/deploy/google-auth-hook.md @@ -6,8 +6,6 @@ title: Google Auth Hook This part of the tutorial shows how to create a sign-in flow for users and integrate with Unleash server project. The implementation assumes that I am working in `localhost` with `4242` port. -**If you are still using Unleash v3 you need to follow the [google-auth-hook-v3](google-auth-v3)** - This is a simple `index.ts` server file. ```javascript diff --git a/website/docs/using-unleash/deploy/google-auth-v3.md b/website/docs/using-unleash/deploy/google-auth-v3.md deleted file mode 100644 index e301fa1ecac7..000000000000 --- a/website/docs/using-unleash/deploy/google-auth-v3.md +++ /dev/null @@ -1,254 +0,0 @@ ---- -title: Google Auth v3 ---- - -> You can also find the complete [source code for this guide](https://github.com/Unleash/unleash-examples/tree/main/v3/securing-google-auth) in the unleash-examples project. - -This part of the tutorial shows how to create a sign-in flow for users and integrate with Unleash server project. The implementation assumes that I am working in `localhost` with `4242` port. - -This is a simple `index.ts` server file. - -```javascript -const unleash = require('unleash-server'); - -unleash.start(options).then((unleash) => { - console.log(`Unleash started on http://localhost:${unleash.app.get('port')}`); -}); -``` - -### Creating a web application client ID {#creating-a-web-application-client-id} - -1. Go to the credentials section in the [Google Cloud Platform Console](https://console.cloud.google.com/apis/credentials?_ga=2.77615956.-1991581217.1542834301). - -2. Click **OAuth consent screen**. Type a product name. Fill in any relevant optional fields. Click **Save**. - -3. Click **Create credentials > OAuth client ID**. - -4. Under **Application type**, select **Web Application**. - -5. Type the **Name**. - -6. Under **Authorized redirect URIs** enter the following URLs, one at a time. - -``` -http://localhost:4242/api/auth/callback -``` - -7. Click **Create**. - -8. Copy the **CLIENT ID** and **CLIENT SECRET** and save them for later use. - -### Add dependencies {#add-dependencies} - -Add two dependencies [`@passport-next/passport`](https://www.npmjs.com/package/@passport-next/passport) and [`@passport-next/passport-google-oauth2`](https://www.npmjs.com/package/@passport-next/passport-google-oauth2) inside `index.ts` file - -```js -const unleash = require('unleash-server'); -const passport = require('@passport-next/passport'); -const GoogleOAuth2Strategy = - require('@passport-next/passport-google-oauth2').Strategy; -``` - -### Configure the Google strategy for use by Passport.js {#configure-the-google-strategy-for-use-by-passportjs} - -OAuth 2-based strategies require a `verify` function which receives the credential (`accessToken`) for accessing the Google API on the user's behalf, along with the user's profile. The function must invoke `cb` with a user object, which will be set at `req.user` in route handlers after authentication. - -```js -const GOOGLE_CLIENT_ID = '...'; -const GOOGLE_CLIENT_SECRET = '...'; -const GOOGLE_CALLBACK_URL = 'http://localhost:4242/api/auth/callback'; - -passport.use( - new GoogleOAuth2Strategy( - { - clientID: GOOGLE_CLIENT_ID, - clientSecret: GOOGLE_CLIENT_SECRET, - callbackURL: GOOGLE_CALLBACK_URL, - }, - function (accessToken, refreshToken, profile, cb) { - // Extract the minimal profile information we need from the profile object - // and connect with Unleash to get name and email. - cb( - null, - new unleash.User({ - name: profile.displayName, - email: profile.emails[0].value, - }), - ); - }, - ), -); -``` - -Add `googleAdminAuth()` function and other options - -```js -function googleAdminAuth(app) {} - -let options = { - adminAuthentication: 'custom', - preRouterHook: googleAdminAuth, -}; - -unleash.start(options).then((instance) => { - console.log( - `Unleash started on http://localhost:${instance.app.get('port')}`, - ); -}); -``` - -### In `googleAdminAuth` function {#in-googleadminauth-function} - -Configure `passport` package. - -```js -function googleAdminAuth(app) { - app.use(passport.initialize()); - app.use(passport.session()); - passport.serializeUser((user, done) => done(null, user)); - passport.deserializeUser((user, done) => done(null, user)); - // ... -} -``` - -Implement a preRouter hook for `/auth/google/login`. It's necessary for login with Google. - -```js -function googleAdminAuth(app) { - // ... - app.get( - '/auth/google/login', - passport.authenticate('google', { scope: ['email'] }), - ); - // ... -} -``` - -Implement a preRouter hook for `/api/auth/callback`. It's a callback when the login is executed. - -```js -function googleAdminAuth(app) { - // ... - app.get( - '/api/auth/callback', - passport.authenticate('google', { - failureRedirect: '/api/admin/error-login', - }), - (req, res) => { - // Successful authentication, redirect to your app. - res.redirect('/'); - }, - ); - // ... -} -``` - -Implement a preRouter hook for `/api/admin`. - -```js -function googleAdminAuth(app) { - // ... - app.use('/api/admin/', (req, res, next) => { - if (req.user) { - next(); - } else { - // Instruct unleash-frontend to pop-up auth dialog - return res - .status('401') - .json( - new unleash.AuthenticationRequired({ - path: '/auth/google/login', - type: 'custom', - message: `You have to identify yourself in order to use Unleash. Click the button and follow the instructions.`, - }), - ) - .end(); - } - }); - // ... -} -``` - -### The complete code {#the-complete-code} - -The `index.ts` server file. - -```js -'use strict'; - -const unleash = require('unleash-server'); -const passport = require('@passport-next/passport'); -const GoogleOAuth2Strategy = require('@passport-next/passport-google-oauth2'); - -const GOOGLE_CLIENT_ID = '...'; -const GOOGLE_CLIENT_SECRET = '...'; -const GOOGLE_CALLBACK_URL = 'http://localhost:4242/api/auth/callback'; - -passport.use( - new GoogleOAuth2Strategy( - { - clientID: GOOGLE_CLIENT_ID, - clientSecret: GOOGLE_CLIENT_SECRET, - callbackURL: GOOGLE_CALLBACK_URL, - }, - (accessToken, refreshToken, profile, cb) => { - cb( - null, - new unleash.User({ - name: profile.displayName, - email: profile.emails[0].value, - }), - ); - }, - ), -); - -function googleAdminAuth(app) { - app.use(passport.initialize()); - app.use(passport.session()); - passport.serializeUser((user, done) => done(null, user)); - passport.deserializeUser((user, done) => done(null, user)); - - app.get( - '/auth/google/login', - passport.authenticate('google', { scope: ['email'] }), - ); - app.get( - '/api/auth/callback', - passport.authenticate('google', { - failureRedirect: '/api/admin/error-login', - }), - (req, res) => { - res.redirect('/'); - }, - ); - - app.use('/api/admin/', (req, res, next) => { - if (req.user) { - next(); - } else { - return res - .status('401') - .json( - new unleash.AuthenticationRequired({ - path: '/auth/google/login', - type: 'custom', - message: `You have to identify yourself in order to use Unleash. Click the button and follow the instructions.`, - }), - ) - .end(); - } - }); -} - -const options = { - adminAuthentication: 'custom', - preRouterHook: googleAdminAuth, -}; - -unleash.start(options).then((instance) => { - console.log( - `Unleash started on http://localhost:${instance.app.get('port')}`, - ); -}); -``` diff --git a/website/docs/using-unleash/deploy/securing-unleash-v3.md b/website/docs/using-unleash/deploy/securing-unleash-v3.md deleted file mode 100644 index aace7729a0cb..000000000000 --- a/website/docs/using-unleash/deploy/securing-unleash-v3.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: Securing Unleash v3 ---- - -> This guide is only relevant if you are using Unleash Open-Source. The Enterprise edition does already ship with a secure setup and multiple SSO options. - -The Unleash API is split into two different paths: `/api/client` and `/api/admin`. This makes it easy to have different authentication strategy for the admin interface and the client-api used by the applications integrating with Unleash. - -## General settings {#general-settings} - -Unleash uses an encrypted cookie to maintain a user session. This allows users to be logged in across multiple instances of Unleash. To protect this cookie, Unleash will automatically generate a secure token the first time you start Unleash. - -## Securing the Admin API {#securing-the-admin-api} - -To secure the Admin API, you have to tell Unleash that you are using a custom admin authentication and implement your authentication logic as a preHook. - -```javascript -const unleash = require('unleash-server'); -const myCustomAdminAuth = require('./auth-hook'); - -unleash - .start({ - databaseUrl: 'postgres://unleash_user:passord@localhost:5432/unleash', - adminAuthentication: 'custom', - preRouterHook: myCustomAdminAuth, - }) - .then((unleash) => { - console.log( - `Unleash started on http://localhost:${unleash.app.get('port')}`, - ); - }); -``` - -Additionally, you can trigger the admin interface to prompt the user to sign in by configuring your middleware to return a `401` status on protected routes. The response body must contain a `message` and a `path` used to redirect the user to the proper login route. - -```json -{ - "message": "You must be logged in to use Unleash", - "path": "/custom/login" -} -``` - -Examples of custom authentication hooks: - -- [google-auth-hook.js](https://github.com/Unleash/unleash-examples/blob/7ed25f97a31dfd8f773c00847080b1a4c889fd87/v3/securing-google-auth/google-auth-hook.js) -- [basic-auth-hook.js](https://github.com/Unleash/unleash-examples/blob/7ed25f97a31dfd8f773c00847080b1a4c889fd87/v3/securing-basic-auth/basic-auth-hook.js) -- [keycloak-auth-hook.js](https://github.com/Unleash/unleash-examples/blob/7ed25f97a31dfd8f773c00847080b1a4c889fd87/v3/securing-keycloak-auth/keycloak-auth-hook.js) - -## Securing the Client API {#securing-the-client-api} - -A common way to support client access is to use pre-shared secrets. This can be solved by having clients send a shared key in an HTTP header with every client request to the Unleash API. All official Unleash clients should support this. - -In the [Java client](https://github.com/Unleash/unleash-client-java#custom-http-headers) this would look like this: - -```java -UnleashConfig unleashConfig = UnleashConfig.builder() - .appName("my-app") - .instanceId("my-instance-1") - .unleashAPI(unleashAPI) - .customHttpHeader("Authorization", "12312Random") - .build(); -``` - -On the Unleash server side, you need to implement a preRouter hook which verifies that all calls to `/api/client` include this pre-shared key in the defined header. This could look something like this. - -```javascript -const unleash = require('unleash-server'); -const sharedSecret = '12312Random'; - -unleash - .start({ - databaseUrl: 'postgres://unleash_user:passord@localhost:5432/unleash', - preRouterHook: (app) => { - app.use('/api/client', (req, res, next) => { - if (req.header('authorization') !== sharedSecret) { - res.sendStatus(401); - } else { - next(); - } - }); - }, - }) - .then((unleash) => { - console.log( - `Unleash started on http://localhost:${unleash.app.get('port')}`, - ); - }); -``` - -[client-auth-unleash.js](https://github.com/Unleash/unleash-examples/blob/7ed25f97a31dfd8f773c00847080b1a4c889fd87/v3/securing-client-auth/index.js) diff --git a/website/docs/using-unleash/deploy/securing-unleash.md b/website/docs/using-unleash/deploy/securing-unleash.md index 24bdb61a9b1d..fe5f0f31246a 100644 --- a/website/docs/using-unleash/deploy/securing-unleash.md +++ b/website/docs/using-unleash/deploy/securing-unleash.md @@ -2,8 +2,6 @@ title: Securing Unleash --- -**If you are still using Unleash v3 you need to follow the [securing-unleash-v3](./securing-unleash-v3)** - > This guide is only relevant if you are using Unleash Open-Source. The Enterprise edition does already ship with multiple SSO options, such as SAML 2.0, OpenID Connect. Unleash Open-Source v4 comes with username/password authentication out of the box. In addition Unleash v4 also comes with API token support, to make it easy to handle access tokens for Client SDKs and programmatic access to the Unleash APIs.