2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have 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>
    
    

動作確認

参考情報

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?