LoginSignup
2
1

More than 1 year has passed since last update.

Vue.js + Keycloak(Docker) ローカル環境構築方法メモ

Posted at
  • 検証用にVue.jsアプリとDocker起動しているKeycloakを接続してみたため、手順をメモしておく。

構成

keycloak_test   -   docker-compose.yml
                -   fe - app-vue

Keycloakコンテナ作成

docker-compose.ymlの準備

  • docker-compose.yml

    • Keycloak起動用
  version: "3"

  volumes:
    mysql_data:
      driver: local

  services:
    mysql:
      image: mysql:5.7
      volumes:
        - mysql_data:/var/lib/mysql
      environment:
        MYSQL_ROOT_PASSWORD: root
        MYSQL_DATABASE: keycloak
        MYSQL_USER: keycloak
        MYSQL_PASSWORD: password
    keycloak:
      image: quay.io/keycloak/keycloak:latest
      container_name: "keycloak"
      environment:
        DB_VENDOR: MYSQL
        DB_ADDR: mysql
        DB_DATABASE: keycloak
        DB_USER: keycloak
        DB_PASSWORD: password
        KEYCLOAK_USER: admin
        KEYCLOAK_PASSWORD: P@ssw0rd
      ports:
        - 8080:8080
      depends_on:
        - mysql

コンテナ起動

docker-compose up

Keycloak設定

  • http://localhost8080からAdmin Consoleにアクセスする。認証情報は、docker-compose.ymlを参照のこと。
  • こちらの手順(「Create a realm」から...)に従い、Keycloak設定を行う。

Vue.js フロント部分作成

プロジェクト作成

cd fe
vue init webpack-simple app-vue 

※すべてデフォルトを選択する。

依存ライブラリインストール

npm i keycloak-js --save
npm i vuejs-logger --save

コード修正

  • こちらを参考にmain.js,App.vueを修正する。

  • main.js

    • initOptionsに対して、以下の修正を行っている。
    • realm:自環境に合わせて修正
    • CheckLoginiframe:追加
  import Vue from 'vue'
  import App from './App.vue'
  import VueLogger from 'vuejs-logger';
  import * as Keycloak from 'keycloak-js';

  Vue.use(VueLogger);

  let initOptions = {
    url: 'http://127.0.0.1:8080/auth', realm: 'myrealm', clientId: 'app-vue', onLoad: 'login-required',CheckLoginiframe:false
  }

  let keycloak = Keycloak(initOptions);

  keycloak.init({ onLoad: initOptions.onLoad, checkLoginIframe:initOptions.CheckLoginiframe }).then((auth) => {
    if (!auth) {
      window.location.reload();
    } else {
      Vue.$log.info("Authenticated");

      new Vue({
        el: '#app',
        render: h => h(App, { props: { keycloak: keycloak } })
      })
    }

  //Token Refresh
    setInterval(() => {
      keycloak.updateToken(70).then((refreshed) => {
        if (refreshed) {
          Vue.$log.info('Token refreshed' + refreshed);
        } else {
          Vue.$log.warn('Token not refreshed, valid for '
            + Math.round(keycloak.tokenParsed.exp + keycloak.timeSkew - new Date().getTime() / 1000) + ' seconds');
        }
      }).catch(() => {
        Vue.$log.error('Failed to refresh token');
      });
    }, 6000)

  }).catch(() => {
    Vue.$log.error("Authenticated Failed");
  });
  • App.vue
  <template>
    <div id="app">
      <img src="./assets/logo.png" />
      <h1>{{ msg }}</h1>
      <h2>User: {{ keycloak.idTokenParsed.preferred_username }}</h2>
      <div>
        <button class="btn" @click="keycloak.logout()">Logout</button>
      </div>
      <div id="wrapper">
        <div class="jwt-token">
          <h3 style="color: black">JWT Token</h3>
          {{ keycloak.idToken }}
        </div>
        <div class="jwt-token">
          <h3 style="color: black">Info</h3>
          <ul>
            <li>clientId: {{ keycloak.clientId }}</li>
            <li>Auth Server Url: {{ keycloak.authServerUrl }}</li>
          </ul>
        </div>
      </div>
      <h2>Essential Links</h2>
      <ul>
        <li><a href="https://keycloak.org" target="_blank">Keycloak</a></li>
        <li>
          <a
            href="https://github.com/keycloak/keycloak-quickstarts"
            target="_blank"
            >Code Repo</a
          >
        </li>
        <li>
          <a href="https://twitter.com/keycloak" target="_blank">Twitter</a>
        </li>
      </ul>
    </div>
  </template>

  <script>
  export default {
    name: "app",
    props: ["keycloak"],
    data() {
      return {
        msg: "Welcome to Your Secured Vue.js App with Keycloak",
      };
    },
  };
  </script>

  <style>
  #app {
    font-family: "Avenir", Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
    margin-top: 60px;
  }

  h1,
  h2 {
    font-weight: normal;
  }

  ul {
    list-style-type: none;
    padding: 0;
  }

  li {
    display: block;
    margin: 0 10px;
    color: #333;
    font-size: 20px;
  }

  a {
    color: #42b983;
  }

  #wrapper {
    display: flex;
    margin-top: 100px;
  }

  .jwt-token {
    width: 50%;
    display: block;
    padding: 20px;
    margin: 10 0 10px;
    font-size: 13px;
    line-height: 1.42857143;
    color: #333;
    word-break: break-all;
    word-wrap: break-word;
    background-color: #f5f5f5;
    border: 1px solid #ccc;
    border-radius: 4px;
    color: #d63aff;
    font-weight: bolder;
  }

  .btn {
    color: #fff;
    background-color: #0088ce;
    border-color: #00659c;
    padding: 6px 10px;
    font-size: 14px;
    line-height: 1.3333333;
    border-radius: 1px;
  }
  </style>

動作確認

  • 起動
  npm run dev -- --port 3000

keycloak-vue.png

参考情報

2
1
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
2
1