React に Keycloak認証を Docker で実装してみる

作成：2023年4月15日
[前回までに作成](https://qiita.com/RYO_/items/758dc99c7dd8f49c785e)した React の APIクライアントに login/logout の認証機能を追加するための準備として、Reactアプリを新たに作って Keycload認証を試してみます。

環境： macOS 12.6.5

# Keycloak を Docker で立てる
次のコマンドで立てます。
```:console
% docker run -d -p 8080:8080 -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin --name keycloak jboss/keycloak
```

keycloak の設定を進めます。ブラウザを起動し、http://localhost:8080/auth にアクセスします。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298045/8d567bb3-2785-2890-aebc-01ea07cebdd1.png">
「Administration Console >」を押します。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298045/2deccc15-39ff-afe6-e989-dd4b0f085711.png">
上記コマンドのパスワードで管理者でログインします。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298045/8249076b-8e1b-07a6-3242-fadfc4a4771d.png">
## レルム作成
レルムを追加します。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298045/c156a688-0e25-9dfb-a4ff-3d7ffa4a4494.png">
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298045/6e465839-bf33-405b-c351-98e906af41a1.png">
## ユーザ作成
ユーザを追加します。[Users]-[Add user]
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298045/8c5233e3-f62a-079f-9879-993a32010233.png">
Username にユーザーネームを入力して Save を押します。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298045/f4ce9c0d-245a-e267-a523-4ac43455f48f.png">
Credentials のタブを押して Password に入力し、 Temporary は OFF にしておきます。set password を押します。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298045/c68cf563-fc85-3696-8b4c-ab03ef824dd2.png">
アカウント管理コンソールに入ります。
http://localhost:8080/auth/realms/test_realm/account/
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298045/2cf1255d-8972-b632-227e-dcfc477574c2.png">
画面右上の「Sign In」ボタンを押して、ユーザーでログインしてみます。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298045/3b08ff0c-3f24-f035-3f2e-c15d7b851d7c.png">
user1 でログインできました！
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298045/6c4feefc-82da-f621-2c45-0a21697be4e6.png">

## Client作成
Clients画面で Createボタンを押します。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298045/3dcf6ae9-f86d-8d1d-d875-91151b1a75ee.png">
Client ID に名前を入れて、Root URL には
http://localhost:3000/
を入力して Saveボタンを押します。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298045/616d9756-dd59-9271-4ac4-d5038271e533.png">

# Reactアプリ作成

新しい Reactアプリ keycloak-react20230414 を作ります
```:console
% npx create-react-app keycloak-react20230414
% yarn start
```
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298045/ac084c86-6c34-ec1d-cfa5-8aeae95b9bb1.png">

各種インストールします。
```:console
% yarn add keycloak-js @react-keycloak/web react-router-dom
```
以下のファイルのコードを更新/作成します（[Githubコード置き場：qiita20230415d](https://github.com/ryoyuki6/keycloak-react20230414/tree/qiita20230415d)）
・App.js
・Keycloak.js　（ realm と clientId を作成した名前に合わせます）
・Nav.js

実行します。ボタンを押してログイン/ログアウトできるようになりました
```:console
% yarn start
```
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298045/edec74bd-001c-39c3-b188-efc20174a03a.png">
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298045/d352fc05-d006-f514-5bf7-69ea7cf006ed.png">
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298045/6d2df8ce-0392-6208-7616-a9c5c158b493.png">

# 苦労した点

実行すると、アプリが Keycloakサーバーへアクセスを繰り返してループに入ってしまいました。
調べたところ、 React 18 以降で発生している現象とのことで、[index.js](https://github.com/ryoyuki6/keycloak-react20230414/blob/qiita20230415d/src/index.js) で StrictMode を削除して解決しました。
[参考情報１](https://stackoverflow.com/questions/73627290/react-keycloak-js-error-login-required-loop-when-accessing-home-page)、[参考情報2](https://github.com/react-keycloak/react-keycloak/issues/182)

# 今後

[前回までに作成](https://qiita.com/RYO_/items/758dc99c7dd8f49c785e)した React の APIクライアントに今回作成した login/logout の認証機能を追加していきたいと思います。


# 参考
・[サンプルコード：https://codesandbox.io/](https://codesandbox.io/s/react-591cru?file=/src/App.js)
・[How to implement Keycloak authentication in React](https://blog.logrocket.com/implement-keycloak-authentication-react/)
　　リンクをクリックしたときに、認証されている時だけリンク先に遷移させる方法が記載されている
・[keycloak or React or NestJS](https://qiita.com/harimogura/items/d867177e705178d8af06)
　　keycloakはフックで提供されているので、useKeycloak()で呼び出します。
　　初期化に時間がかかるので、スピナ表示で初期化完了を待ちます。
・[初期化のスピナ表示のサンプルコード](https://github.com/ChristianHuff-DEV/react-keycloak-authentication/blob/main/src/App.tsx)
・[DockerでKeycloakをサクッと立ててSAML検証環境を構築する](https://qiita.com/cold-wisteria/items/557c0d9bd34b9d638f58)
・[jboss/keycloak コンテナを M1 mac(arm64) で起動する](https://qiita.com/tamaki_tech/items/3001577a5db1f0f43b56)
・[Docker, Keycloakを利用しアクセストークンを指定してAPI実行する](https://qiita.com/nayylin/items/41ede2e91d2d916a88b5)
・[Keycloakの認可機能の使い方（OAuth2スコープ編）](https://qiita.com/unhurried/items/7656512c04e51c941480)
・[Keycloakでログイン画面のテーマの背景をとりあえず変えたい](https://qiita.com/henatyokotraveler/items/9acd21af78ae32d3bb25)
・[Keycloakを使ってAPI GatewayでAPIをアクセス制限する](https://qiita.com/rawr/items/abcfa753e1fda43d156c)
・Youtube：[KeycloakでAPI認可に入門する 2022-3-12](https://www.youtube.com/watch?v=zWeqsdUFRMA)
・[How to Providing Keycloak Authentication for React Application](https://medium.com/@aalam-info-solutions-llp/how-to-providing-keycloak-authentication-for-react-application-27cab703a386)
OpenID Connect (OIDC) is an authentication protocol that is an extension of OAuth 2.0. While OAuth 2.0 is only a framework for building authorization protocols and is mainly incomplete, OIDC is a full-fledged authentication and authorization protocol.
OIDC also makes heavy use of the Json Web Token (JWT) set of standards. These standards define an identity token JSON format and ways to digitally sign and encrypt that data in a compact and web-friendly way.