之前在 Nextjs 這邊能夠讀取到 Directus 中的資料是因為將資料權限設定成了 Public,如果資料非開放又要讓用戶需要登入之後才能取得資料的話,就要能夠在 Nextjs 中取得 Directus 的權限。
如此就需要設定讓 Directus 的 cookie 能夠被不同站點的 Nextjs 讀取到。
AUTH_KEYCLOAK_MODE="session" # AUTH_<provider>_MODE
SESSION_COOKIE_DOMAIN="localhost:8055" # Replace XXXX with the domain of your Directus instance. For example "directus.myserver.com"
SESSION_COOKIE_SECURE="true"
SESSION_COOKIE_SAME_SITE="None"
不過為了在 localhost 上能夠測試,得先設定的再寬鬆點
AUTH_KEYCLOAK_MODE="session" # AUTH_<provider>_MODE
# For production
# SESSION_COOKIE_DOMAIN="localhost:8055" # Replace XXXX with the domain of your Directus instance. For example "directus.myserver.com"
# SESSION_COOKIE_SECURE="true"
# SESSION_COOKIE_SAME_SITE="None"
#For testing Seamless SSO locally
SESSION_COOKIE_SECURE="false"
SESSION_COOKIE_SAME_SITE="lax"
這邊設定完先不急著重開容器,要先設定好使用者權限。
先登入 Directus 後台移除先前設定開放的資料權限,然後另外新增一個 Role。
在 Role 當中設定一個新的 Policy,使之能夠讀取資料
儲存離開前可以先複製一下網址,主要是需要這個 Role 的 uuid。
然後新增一個容器設定:
AUTH_KEYCLOAK_DEFAULT_ROLE_ID="preferred_default_role_id" #AUTH_<provider>_DEFAULT_ROLE_ID
昨天登入後使用者沒有任何角色或權限,就是缺了這個設定,這樣設定後當有經由這個管道建立帳號的用戶就會預設配給這個 Role。
再來就重開容器,然後看是要試著重新從 Keycloak 登入一個新用戶,或是將之前的用戶配給上面新增的 Role。
再來 Nextjs 這邊就能設登入 Directus 取得權限了。
在進行登入前可以先確認看看,取得資料的 api 應該已經被擋了。
首先在 authentication
跟 rest
模塊上都設定請求要帶上 cookie。
const client = createDirectus<Schema>("http://localhost:8055")
.with(authentication("session", { credentials: "include" }))
.with(rest({ credentials: "include" }));
登入 Directus 要跳轉到給 Directus 用的 Keycloak 登入畫面,注意設定好跳轉回來的網址redirect
。
<a href="http://localhost:8055/auth/login/keycloak?redirect=http://localhost:3000/post">
Login
</a>
登入成功後要定期更新 token
await client.refresh()
這樣就能試著讀取資料了。
這樣Nextjs 本身有經由 NextAuth 使用 Keycloak 的登入,跟在 Directus 使用 Keycloak 的登入,要來想個辦法把兩邊縫在一塊爾。