はじめに

今回の記事では、Keycloakを使ってユーザーを作成し、そのユーザー名を画面に表示できるところまでを実践していきます。

なぜ環境構築なのか?

日々の開発の中で、一番時間を取られるのは環境構築じゃないかと思います。
手順書が古かったり、追加の対応が必要だったりで「手順通りにやったのにエラー!」という経験、みなさんもあるのではないでしょうか?

自分自身、環境構築には苦手意識があり、そこで今回はあえて環境構築をテーマにして苦手意識を減らしていこうと記事をまとめていこうかと思います。

ただフロントだけだと簡単すぎるかもしれないので、少し複雑さを足すためにKeycloakを組み合わせようと思います。

Keycloakってなに?

Keycloakは、オープンソースの「認証・認可」を担うサービスです。
ログインやユーザー管理をアプリに組み込むのではなく、Keycloakに任せることで簡単に導入できます。

例えば、社内システムで勤怠管理や経費精算ツールなど複数のサービスを使う場合、毎回ログインするのは面倒ですよね。
そんな時にKeycloakを使えば「一度ログインすれば全部使える(SSO)」という仕組みが作れます。

今回の記事では細かい機能までは触れませんが、「ログイン処理をKeycloakに外注できる」ぐらいのイメージで読んでいただければと思います。

Keycloak側の設定

今回は手軽に環境を汚さないのでDockerで起動を行おうと思います。
Dockerをダウンロードしていない場合は公式ダウンロードページからダウンロードをしてください。

ダウンロードが完了したらターミナルで下記を実行してください。

`docker run --name keycloak -p 8080:8080 \
  -e KEYCLOAK_ADMIN=admin \
  -e KEYCLOAK_ADMIN_PASSWORD=admin \
  quay.io/keycloak/keycloak:latest start-dev`

実行後、http://localhost:8080 へアクセスするとkeycloak の画面が表示されると思うので、Usernameadmin Passwordadmin でログインをしてください。keycloak のversionは26.3.3

Realmの作成

Keycloakへログインできたら次はRealmの作成です。
左側にあるメニューのManage realmsCreate realmを押下後、Realm namedemoを入力しCreateを押下して作成完了です。

Clientsの作成

Realmの作成が完了したら次はClientsです。
左側にあるメニューのClientsCreate client を押下します。
①のGeneral settingsはClient IDtest-appを入力してnext
②のCapability configは何も設定せずにnext
③のLogin settingsはRoot URLhttp://localhost:4200/Valid redirect URIshttp://localhost:4200/*Web origins*を設定してSaveを押下してください。

Usersの作成

最後にUserを作成します。
左側にあるメニューのUsersAdd user を押下します。
Usernametestuserを入力してCreate
作成が完了するとUser detailsが表示されるので、Credentialsタブ→Set passwordを押して任意のパスワードを設定してください。

動作確認

ここまで色々と設定や作成を行ってきましたが、そもそも「Realm」とは何なのか?とイメージが付きにくい方もいるかと思います。
簡単に例えるとRealmは学校そのもので、その中で生徒(User)やクラス(Client)が管理されているイメージです。
学校ごとにルールや管理者が異なるため、Keycloakに最初から用意されているmasterRealmは触らず、
今回は「環境構築用の学校」を新しく設立した、という感覚で捉えると分かりやすいと思います。
それでは、実際に動作確認をしてみましょう。
下記をブラウザでアクセスしてみてください。※一行に繋げてアクセス

http://localhost:8080/realms/demo/protocol/openid-connect/auth
  ?client_id=test-app 
  &redirect_uri=http://localhost:4200/
  &response_type=code
  &scope=openid

?client_id=test-app:Keycloakに登録したクライアントID
&redirect_uri=http://localhost:4200/:認証後にリダイレクトするコールバックURL
&response_type=code:OIDCのレスポンスタイプ
&scope=openid:要求するスコープ(権限の範囲)

アクセスすると作成したrealm:demoのログイン画面が表示されるので、先ほど作成したUsertestuserでログインしてみてください。

ログインが成功すると先ほど設定したhttp://localhost:4200/にリダイレクトされるはずです。

まだAngular側の設定をしていないので404になりますが、Keycloakでユーザーを作成し、そのユーザーでログインができる所まで確認できました!

Angularの設定

keycloak側の設定が完了したので、連携するためにAngularプロジェクトの新規作成を行います。

Angularプロジェクトの作成

使用しているAngular CLIの情報です。

任意のフォルダ配下にプロジェクトを新規作成します。

ng new keycloak-demo

作成したらプロジェクトに移動して起動できるか確認します。

cd keycloak-demo
ng serve -o

ブラウザでhttp://localhost:4200にアクセスしてください。
下記画面が表示されたら成功です。

Keycloak用のライブラリをインストール

Keycloakと連携するために必要なライブラリをインストールします。

npm install keycloak-angular keycloak-js

Keycloak初期設定ファイルを作成

src/app配下にinit-keycloak.tsを作成してください

import { KeycloakService } from 'keycloak-angular';

export function initializeKeycloak(keycloak: KeycloakService) {
  return () =>
    keycloak.init({
      config: {
        url: 'http://localhost:8080/',
        realm: 'demo',
        clientId: 'test-app',
      },
      initOptions: {
        onLoad: 'login-required',
        pkceMethod: 'S256',
        redirectUri: window.location.origin,
      },
    });
}

既存ファイルの修正

src/app配下のapp.config.tsapp.htmlapp.tsを以下の内容で書き換えてください。
app.config.tss

import { ApplicationConfig, APP_INITIALIZER, provideZoneChangeDetection, provideBrowserGlobalErrorListeners } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient } from '@angular/common/http';

import { routes } from './app.routes';

import { KeycloakAngularModule, KeycloakService } from 'keycloak-angular';
import { initializeKeycloak } from './init-keycloak';

export const appConfig: ApplicationConfig = {
  providers: [
    provideBrowserGlobalErrorListeners(),
    provideZoneChangeDetection({ eventCoalescing: true }),
    provideRouter(routes),
    provideHttpClient(),
    KeycloakAngularModule,
    KeycloakService,
    {
      provide: APP_INITIALIZER,
      useFactory: initializeKeycloak,
      multi: true,
      deps: [KeycloakService],
    },
  ],
};

app.html

<main class="main">
  @if (userName) {
    <div class="user-info">
      <p>ようこそ、{{ userName }} さん!</p>
    </div>
  }
</main>

app.ts

import { Component, signal, OnInit } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { KeycloakService } from 'keycloak-angular';

@Component({
  selector: 'app-root',
  imports: [RouterOutlet],
  templateUrl: './app.html',
  styleUrls: ['./app.css']
})
export class App implements OnInit {
  protected readonly title = signal('keycloak-demo');
  userName: string | null = null;

  constructor(private keycloakService: KeycloakService) {}

  async ngOnInit() {
    const isLoggedIn = await this.keycloakService.isLoggedIn();

    if (isLoggedIn) {
      try {
        const userProfile = await this.keycloakService.loadUserProfile();
        this.userName = userProfile.username ?? null;
      } catch (error) {
        console.error('ユーザープロファイルの取得に失敗しました', error);
      }
    }
  }
}

ここまで作成・修正ができたらng serve -oで起動してみてください。
ブラウザ http://localhost:4200にアクセスしたらKeycloakのログイン画面にリダイレクトされて、ログインが成功したら「ログインユーザー: ユーザー名」 が画面に表示されるはずです。

最後に

いかがだったでしょうか。
今回はKeycloakを使ってユーザーを作成し、ログインユーザー名をAngularの画面に表示するところまでを実施しました。

単なる手順書通りの環境構築では「なぜそうなるのか」が見えにくく、エラー時の原因特定も難しくなりがちです。
ですがシステムの流れを意識しながら進めることで理解が深まり、トラブル対応力も上がると感じています。

記事上では淡々と進んでいるように見えるかもしれませんが、実際には既存のAngular依存関係に悩まされたり、思わぬエラーに詰まったりしました。そうした対応も含めて、この記事がこれから環境構築に挑戦する方の「知識の引き出し」の一つになれば嬉しいです。

ここまで読んでいただき、ありがとうございました!
後半ではSpring Bootと連携してAPIを呼び出し、フロントとバックエンドを動かすところまで進める予定です。ぜひご期待ください!