LoginSignup
17
11

More than 3 years have passed since last update.

React & Keycloakでユーザー認証する

Last updated at Posted at 2019-11-08

React & Keycloakでユーザー認証する

目標

  • Reactでユーザー認証
  • 認証にはKeycloakを使う
  • docker-composeで一発立ち上げ

リポジトリ

Keycloak

今回はDBにMySQLを使う。

Keycloakの設定

以下のdocker-composeを使って一度Keycloakを起動する。
http://localhost:8080を開いて管理画面からRealmとClient、Userを追加する。

docker-compose.yml
version: '3'

services:

  keycloak:
    image: jboss/keycloak:6.0.1
    environment:
      KEYCLOAK_USER: admin
      KEYCLOAK_PASSWORD: password
      DB_VENDOR: MYSQL
      DB_ADDR: keycloak-db
      DB_DATABASE: keycloak
      DB_USER: keycloak
      DB_PASSWORD: password
    ports:
      - 8080:8080
    depends_on:
      - keycloak-db

  keycloak-db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: keycloak
      MYSQL_USER: keycloak
      MYSQL_PASSWORD: password

今回は以下のように登録した。

  • Realm: demo
  • Client:
    • Client ID: demo-client
    • RootURL: http://localhost:3000/
  • User:
    • FirstName: John
    • LastName: Smith
    • EMail: john.smith@mail.com
    • Password: passward

Installationファイルの取得

Clients>demo-client>InstallationからKeycloak OIDC JSONをダウンロードする。

keycloak.json
{
  "realm": "demo",
  "auth-server-url": "http://localhost:8080/auth",
  "ssl-required": "external",
  "resource": "demo-client",
  "public-client": true,
  "confidential-port": 0
}

データのExport

Keycloakのプロセスに入って以下のコマンドを打ち込む。
投入したデータが指定したファイルにExportされたあとKeycloakが再起動する。

# keycloak/bin/standalone.sh \
  -Djboss.socket.binding.port-offset=100 \
  -Dkeycloak.migration.action=export \
  -Dkeycloak.migration.provider=singleFile \
  -Dkeycloak.migration.realmName=demo \
  -Dkeycloak.migration.usersExportStrategy=REALM_FILE \
  -Dkeycloak.migration.file=/tmp/import-demo.json

Exportされたjsonを回収する。

$ docker cp <CONTAINER ID>:/tmp/import-demo.json import-demo.json

Dockerfileの作成

初回起動時にExportしたjsonをImport出来るようにDockerfileを作成する。

Dockerfile
FROM jboss/keycloak:6.0.1

ADD import-demo.json /opt/jboss/keycloak/

CMD ["-b", "0.0.0.0", "-Dkeycloak.import=/opt/jboss/keycloak/import-demo.json"]

これでKeycloakの初回起動時にRealmとClient、UserがImportされるようになった。

React

今回はTypeScriptで実装

プロジェクトの作成

create-react-app等でざっくりプロジェクトを作る。

$ npx create-react-app react-spa-keycloak --scripts-version=react-scripts-ts

keycloak-jsをインストール。
見た目も多少魅せたいからBootstrap追加。

$ npm install keycloak-js
$ npm install bootstrap
$ npm install react-bootstrap

publicディレクトリに前項で取得したkeycloak.jsonを配置する。

キモになる部分はこの部分。
keycloakによるログインが必須であること、認証が成功したときのみUserInfo.tsx
表示することを書くだけ。
煩わしい認証処理は全てkeycloak-jsがやってくれる!

Secured.tsx
const Secured: React.FC = () => {

  const keycloak = Keycloak('/keycloak.json');
  const [keycloakState, setKeycloakState] = useState<KeycloakState>({keycloak: null, authenticated: false});

  useEffect(() => {
    keycloak.init({onLoad: 'login-required'})
      .success((authenticated) => {
        setKeycloakState({keycloak: keycloak, authenticated: authenticated});
      });
  }, []);

  if (keycloakState.keycloak !== null) {
    if (keycloakState.authenticated) {
      return (
        <div>
          <Alert variant="success">
            <Alert.Heading>Authenticated</Alert.Heading>
          </Alert>
          <UserInfo keycloakState={keycloakState}/>
          <Logout keycloakState={keycloakState}/>
        </div>
      );
    } else {
      return (
        <div>
          <Alert variant="danger">
            <Alert.Heading>Unable to authenticate</Alert.Heading>
          </Alert>
        </div>
      )
    }
  }

  return (
    <div>
      <p>Initializing Keycloak...</p>
    </div>
  );
};

export default Secured;

Dockerfileの作成

ReactアプリケーションもDocker化する。

Dockerfile
FROM node:latest

WORKDIR /app

COPY package.json /app
RUN npm install

COPY . /app
RUN npm run build

CMD ["npm", "start"]

DockerCompose化

最後の仕上げ。

docker-compose.yml
version: '3'

services:

  keycloak:
    build: ./keycloak
    environment:
      KEYCLOAK_USER: admin
      KEYCLOAK_PASSWORD: password
      DB_VENDOR: MYSQL
      DB_ADDR: keycloak-db
      DB_DATABASE: keycloak
      DB_USER: keycloak
      DB_PASSWORD: password
    ports:
      - 8080:8080
    depends_on:
      - keycloak-db

  keycloak-db:
    image: mysql:5.7
    volumes:
      - ./keycloak/db:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: keycloak
      MYSQL_USER: keycloak
      MYSQL_PASSWORD: password

  react-spa-keycloak:
    build: .
    ports:
      - 3000:3000

実行

docker-compose up

http://localhost:3000/をブラウザで開く。

localhost_3000_.png

john.smith@email.com/password

localhost_8080_auth.png

おおー!

localhost_3000_secured.png

感想

こんなにも簡単にフロントエンドのSSO認証を実装できるなんて!

参考文献

USER AUTHENTICATION WITH KEYCLOAK – PART 1: REACT FRONT-END
https://scalac.io/user-authentication-keycloak-1/

17
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
11