Directus 具備 SSO 功能,這就嘗試來用 Keycloak 登入試試。
首先目前兩邊的服務都跑在 Docker 上,為了讓兩邊的容器能夠連線,需要設定 network 讓兩邊溝通
docker network create awesome-ironman
然後 Keycloak 之前是單獨用 docker 指令跑起來的,為了讓資料持久化跟設定一些參數,也來建立 docker-compose。
docker-compose.yml
version: '3.7'
services:
postgres:
image: postgres
volumes:
- ./data/database:/var/lib/postgresql/data
environment:
POSTGRES_DB: awesome_keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: keycloak
networks:
- awesome-ironman
keycloak:
image: quay.io/keycloak/keycloak:25.0.4
command: start-dev
env_file:
- .env
ports:
- 8080:8080
restart: always
depends_on:
- postgres
networks:
- awesome-ironman
networks:
awesome-ironman:
name: awesome-ironman
external: true
.env
KC_HOSTNAME=localhost
KC_HOSTNAME_PORT=8080
KC_HOSTNAME_STRICT_BACKCHANNEL=false
KC_HTTP_ENABLED=true
KC_HOSTNAME_STRICT_HTTPS=false
KC_HEALTH_ENABLED=true
KC_DB=keycloak
KC_DB_URL=jdbc:postgresql://postgres/awesome_keycloak
KC_DB_USERNAME=keycloak
KC_DB_PASSWORD=keycloak
KEYCLOAK_ADMIN=admin
KEYCLOAK_ADMIN_PASSWORD=admin
KEYCLOAK_FRONTEND_URL=http://localhost:8080/auth
幾個注意點:
http://keycloak:8080/realms/awesome
但主機上的瀏覽器可認不得 network 裡的識別,所以必須將登入頁的網址替換成用 localhost
開頭的。再來 Directus 這邊的設定也要調整一下,首先是將 Directus 的容器也連上 network,再來是在設定上添加幾項:
AUTH_PROVIDERS="keycloak"
AUTH_KEYCLOAK_DRIVER="openid"
AUTH_KEYCLOAK_CLIENT_ID="awesome-directus"
AUTH_KEYCLOAK_CLIENT_SECRET="keycloak_client_secret"
AUTH_KEYCLOAK_ISSUER_URL="http://keycloak:8080/realms/awesome"
AUTH_KEYCLOAK_IDENTIFIER_KEY="preferred_username"
AUTH_KEYCLOAK_ICON="keycloak"
AUTH_KEYCLOAK_LABEL="Keycloak"
AUTH_KEYCLOAK_ALLOW_PUBLIC_REGISTRATION="false"
Valid redirect URI
http://localhost:8055/auth/login/keycloak/callback
# {server_host}/auth/login/{provider}/callback
Valid post logout redirect URI
http://localhost:8055/*
設定到這邊重新啟動容器後,Directus 登入畫面會多出一個 Keycloak 選項。
醜醜的,先不管他。
點下去後就會到 Keycloak 的登入畫面,登入成功後跳轉回 Directus。
但沒登入成功還是報錯
awesome-directus-directus-1 | [13:55:41.030] WARN: [OpenID] Unexpected error during OpenID login
awesome-directus-directus-1 | err: {
awesome-directus-directus-1 | "type": "Error",
awesome-directus-directus-1 | "message": "connect ECONNREFUSED 127.0.0.1:8080",
awesome-directus-directus-1 | "stack":
awesome-directus-directus-1 | Error: connect ECONNREFUSED 127.0.0.1:8080
awesome-directus-directus-1 | at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1555:16)
awesome-directus-directus-1 | "errno": -111,
awesome-directus-directus-1 | "code": "ECONNREFUSED",
awesome-directus-directus-1 | "syscall": "connect",
awesome-directus-directus-1 | "address": "127.0.0.1",
awesome-directus-directus-1 | "port": 8080
awesome-directus-directus-1 | }
看起來還是 Docker 的連線問題,這裡只能下集待續了。