昨天嘗試串接 Directus 跟 Keycloak 時卡在一個連線錯誤上。
awesome-directus-directus-1 | [11:49:28.757] 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 | }
awesome-directus-directus-1 | [11:49:28] GET /auth/login/keycloak/callback?state=UoyBXynnGr8gUqExY6fp75NUCvkWNo1XZ9JYbtOT-zU&session_state=102e1f2a-dc23-4238-a199-c270c158baba&iss=http%3A%2F%2Flocalhost%3A8080%2Frealms%2Fawesome&code=5e8b8177-b97a-4fcd-875e-235b896f5800.102e1f2a-dc23-4238-a199-c270c158baba.aa3bc0b9-8e77-4162-9c8b-243f0c35d08d 302 517ms
到這邊其實 Keycloak 端已經成功登入了,但 Keycloak 回傳給 Directus 的登入資訊中, iss
的資訊預設會以 Keycloak 自己的 client url 開頭,在當下以本地容器啟動的狀態下,就會是 http://localhost:8080。 所以當 Directus 嘗試用這個 iss 進行連線請求 token 時,就會連線失敗。
所以首先設定 Keycloak 改以請求時使用的網域來動態生成 iss ,不要用預設的 client url。
# 當 KC_HOSTNAME_BACKCHANNEL_DYNAMIC 為 true 時,KC_HOSTNAME 必須是完整的網址,不能只有 hostname
KC_HOSTNAME=http://localhost:8080/
KC_HOSTNAME_BACKCHANNEL_DYNAMIC=true
#原本是false,要變更以允許 SSO 登入後自動建立使用者
AUTH_KEYCLOAK_ALLOW_PUBLIC_REGISTRATION=true
再來 Directus 這裡不使用 network 的名稱來進行連線,而是改用 network 上的 ip。
首先要查出 keycloak 在 docker network 上的 IPv4Address。
docker network inspect awesome-ironman
然後替換掉連線 Keycloak 的網址,可能像這樣
AUTH_KEYCLOAK_ISSUER_URL="http://192.168.80.4:8080/realms/awesome"
注意每次 Keycloak 重啟後 ip 可能會變,有變的話就要連帶重啟 Directus。
都設定好重啟後就能嘗試登入啦。
…
也是啦,剛生成的使用者不會有後臺權限。
要先用 admin 帳號登入後,找到剛剛以 SSO 登入後生成的 User,給予 Administrator Role。
再試一次就能成功登入了。