Medley Developer Blog

株式会社メドレーのエンジニア・デザイナーによるブログです

社内勉強会TechLunchで Badging API について発表しました

みなさん、こんにちは。開発本部のエンジニアの舘野です。先日、社内勉強会「TechLunch」で Badging API について発表したので、その内容を紹介させていただきます。

Badging API とは

Badging API とは、ネイティブアプリのアプリアイコン上に表示されるバッジと同様に、ウェブアプリのアイコン上にバッジを表示することができる Web API です。

 

ネイティブアプリで可能なこと全てをウェブアプリでも可能にすることを目指す、Fugu というプロジェクトで実現に向けて動いている API の1つで、Chrome 73 から Origin Trials として利用可能になっています。Origin Trials とは、試験的に特定の開発者に限定してAPIを利用できるようにする仕組みのことで、正式リリース前にAPIに対する有用なフィードバックを受け取ることができるものです。

 

このAPIの最新の概要や仕様については、 WICGGithubBadging APIのリポジトリを用意しているので、そこで確認することができます。

WICG(The Web Incubator Community Group)は、先進的なウェブ技術について検討するコミュニティグループで、W3Cのグループの1つです。

提案されている API のインターフェースは、現時点(2019/08/14)では以下のようになっています。

 

https://github.com/WICG/badging/blob/master/explainer.md#the-api

 

  • Badgewindowオブジェクトのメンバとして持つ
  • Badgeには2つのメソッドが存在する
    • Badge.set()
    • Badge.clear()
  • Badge.set(5)のようにset()に整数を渡してバッジ上に数字を表示する
  • 単にBadge.set()で呼び出すとフラグとしてバッジを表示する
  • Badge.set(5, { scope:  ‘/baz’ })のようにオプションを渡して特定のスコープ配下で表示されるように指定できる
    • オプションでスコープが指定されてない場合、スコープは/になる

ローカル環境で試す

 

実際にどのような形でバッジを表示できるかを確認するために、今回はローカル環境(macOS 10.14、Chrome76)で試してみました。

API自体は非常にシンプルなので、PWAのアプリを用意してインストールするだけで簡単に試すことができます。

インストールされていないウェブアプリでも、タブのfavicon上やブックマークアイコン上にバッジを表示することも議論されているようですが、今のところインストール済みのウェブアプリでしかバッジは表示されません。

 

最初にAPIを利用可能な状態にする必要がありますが、上述の通りAPI自体が現在Origin Trials の段階なので、Origin Trialsの利用申請を行うかローカル環境であればchrome://flagsで実験的な機能を有効にする(#enable-experimental-web-platform-features)かのいずれかを行う必要があります。

 f:id:medley_inc:20190827173844p:plain

今回はローカル環境で試すだけなので、chrome://flagsから enable-experimental-web-platform-features を有効にしておきます。

実験的な機能を利用可能にしたことでBadging API自体は利用可能になりますが、window.Badgeとして利用可能になっているのではなく、Origin Trials の段階ではBadgeではなくExperimentalBadgeとして提供されています。

 

次に、サンプルのプロジェクトを用意してwebpack-dev-serverでローカルサーバを用意します。

 

$ yarn init

$ yarn add --dev webpack webpack-cli webpack-dev-server html-webpack-plugin copy-webpack-plugin

 

webpack-dev-serverでローカルサーバが見れる状態になるようにwebpack.config.jsに設定を記述します。

const path = require('path')

const HtmlWwebpackPlugin = require('html-webpack-plugin')

 

module.exports = {

  mode: 'development',

  devServer: {

    https: true,

  },

  entry: {

    app: ['./src/js/app.js'],

  },

  output: {

    path: path.resolve(__dirname, './dist'),

  },

  plugins: [

    new HtmlWwebpackPlugin({

      template: 'src/index.html',

    }),

  ],

}

 

次にmanifest.jsonを用意します。manifest.jsonは、そのアプリがどういったものか、また、インストールした時にどのように振る舞うかをブラウザに伝えるための設定ファイルになります。

https://app-manifest.firebaseapp.com/ のようなサービスでmanifest.jsonとアイコンを各種サイズ自動生成できるので、今回はこのサービスで生成します。

 

{

  "name": "badging-api-playground",

  "short_name": "badge",

  "theme_color": "#5B5CFD",

  "background_color": "#5B5CFD",

  "display": "standalone",

  "orientation": "portrait",

  "prefer_related_applications": false,

  "Scope": "/",

  "start_url": "/",

  "icons": [

    {

      "src": "images/icons/icon-72x72.png",

      "sizes": "72x72",

      "type": "image/png"

    },

    {

      "src": "images/icons/icon-96x96.png",

      "sizes": "96x96",

      "type": "image/png"

    },

    {

      "src": "images/icons/icon-128x128.png",

      "sizes": "128x128",

      "type": "image/png"

    },

    {

      "src": "images/icons/icon-144x144.png",

      "sizes": "144x144",

      "type": "image/png"

    },

    ….

  ],

  "splash_pages": null

}

 

webpack.config.jsの方にmanifest.jsonをローカルサーバで配信されるように設定を追加しておきます。

 

const path = require('path')

const HtmlWwebpackPlugin = require('html-webpack-plugin')

+ const CopyPlugin = require('copy-webpack-plugin')

 

module.exports = {

  ….

  plugins: [

    ….

+     new CopyPlugin([

+       {

+         from: 'src/manifest.json',

+         to: '',

+       },

+       {

+         from: 'src/images/icons',

+         to: 'images/icons/'

+       },

+     ]),

  ],

}

 

ここまででChromeのApplicationタブからmanifest.jsonが認識されいてることが確認できますが、インストール可能な状態にはなっていません。

f:id:medley_inc:20190826185511p:plain

アプリをインストール可能な状態にするには いくつかの基準 があり、service workerが必要になります。今回はWorkbox のwebpackプラグインで対応します。

 

yarn add --dev workbox-webpack-plugin

workboxにはGenerateSWとinjectManifestの2つのモードがあり、今回はどちらでも問題ないかと思いますがinjectManifestモードを利用します。

 

const path = require('path')

const HtmlWwebpackPlugin = require('html-webpack-plugin')

const CopyPlugin = require('copy-webpack-plugin')

+ const { InjectManifest } = require('workbox-webpack-plugin')

 

module.exports = {

  ….

  plugins: [

    ….

+     new InjectManifest({

 

+       swSrc: path.resolve(__dirname, 'src/sw.js'),

+     }),

  ],

}

 

app.jsの方でservice workerの登録がされるように記述しておきます。

if ('serviceWorker' in navigator) {

  window.addEventListener('load', () => {

    navigator.serviceWorker.register('./sw.js').then((res) => {

      console.log(res)

    }).catch((err) => {

      console.error(err)

    })

  })

}

 

service workerの対応が済むとインストール可能なアプリの基準を満たすので、Chrome76ではアドレスバーにオムニボックスが表示され、そこからインストールが可能になっています。

f:id:medley_inc:20190826185538p:plain

f:id:medley_inc:20190826185554p:plain

インストールするとLaunchpadにアプリアイコンが表示されたので、実際にBadge APIを試してみます。

window.ExperimentalBadge.set()を呼び出すと、フラグとしてバッジがつきます。

f:id:medley_inc:20190826185622p:plain

window.ExperimentalBadge.set(1)のように引数に数値を入れて呼び出すと、バッジは数字が入った状態で表示されます。

f:id:medley_inc:20190826185641p:plain

window.ExperimentalBadge.clear()でバッジがクリアされ、元のアプリアイコンだけの状態に戻ります。

f:id:medley_inc:20190826185653p:plain

非常に簡単ではありますが、このようにしてウェブアプリのアイコンにバッジをつけられることが確認できました。

なお、このサンプルプロジェクトは https://github.com/makotot/badging-api-playground にあげてあります。

 

まとめ

近い将来正式リリースされる可能性が高いAPIを試すことで、今後ウェブアプリでどのようなことが実現可能になっていくかの一端を垣間見ることができました。

 

API自体がOrigin Trialの段階で、ブラウザのタブのfavicon上やブックマークアイコン上に表示したいケースであったり、バッジはどこまでの範囲で適用するべきかのスコープの問題であったり、最終的にどのような形に仕様が整理されるかまだ明確ではない部分もあります。

 

最終的にどのように課題が解決されていくか注目したいと思います。

Google Cloud Next '19 in Tokyo にて、App Maker の活用事例を紹介しました

はじめに

こんにちは、コーポレートエンジニアの若林です。

普段はいわゆる社内SE的な領域を担当していますが、その名の通りエンジニアの視点も持ったコーポレート機能という立ち位置で、社員の働く基盤や事業の発展を支えています。 過去のコーポレートエンジニアの取り組みや、マインドについては以下が参考になるかと思います。

今回もその取り組みの一環で、先日開催された Google Cloud Next '19 in Tokyo に、カスタマースピーカーという形で弊社執行役員の兼松と共に登壇させて頂きました。

今回は、登壇させて頂いたセッション Google Apps Script / AppMaker 最新アップデートと活用のヒント について、セッションでお伝えした内容を含めたレポートを書きたいと思います。

Google Cloud Next '19 in Tokyo について

Google Cloud Next は、年一度 Google 主催で催されるGoogle テクノロジーに関するカンファレンスです(今年は、サンフランシスコ、東京、ロンドンの世界3会場開催)

メドレー社内でも、G Suite を中心に Google Cloud の活用事例が増えてきていることもあり、社内の新しいアプリケーションプラットフォームとして採用している App Maker の話でスピーカー応募してみようということになりました。

なお、登壇させて頂いたセッションですが、一般申込受付が始まってすぐに満席になってしまい、私がSNSでアナウンスしても既に満席で申し込めないような状態になっておりました・・・

会場の雰囲気

f:id:medley_inc:20190821171227j:plain
東京タワーとの一枚

f:id:medley_inc:20190821171259j:plain
登壇の様子(背景と同色なのは偶然です)

セッション内容について

Google Apps Script / AppMaker 最新アップデートと活用のヒント

今回は、Google の深堀さん、嘉穂無線の太田さんとの合同セッションという形で登壇させて頂きました。

まずGoogleの深掘さんが、「G Suite を拡張開発するテクノロジーの全体概要と活用事例」というテーマで、Google Apps Script / App Maker を含む G Suite 周辺の開発プラットフォームについて、位置付けの整理とグローバルでの活用事例、今後のアップデートについてお話されました。次に、嘉穂無線の太田さんが、「Google Apps Script の活用事例」というテーマで、Google Apps Script を活用して開発した社内システムについて、デモを交えて紹介されました。

それを受けて、メドレーでは「Google App Maker 活用事例と開発Tips」というテーマで、Google App Maker を活用して開発した社内システムを、デモを交えて紹介させて頂きました。

App Maker はGAされてからまだ一年強ということもあって、Apps Script と比較してもオンラインに蓄積されているナレッジが非常に少なく(あってもほぼ英語)、現時点において日本で活用できている企業は本当に限られていると思っています。

しかし実際に触っていく中でも非常に可能性を秘めたプラットフォームだと感じているので、日本でも活用する会社が増えてくれれば嬉しいという思いを込めて、今回プレゼンさせて頂きました。

ここからは、実際にメドレーのパートでお話した内容を、振り返りも兼ねて書かせて頂ければと思います。

Google App Maker とは

一言で言うと...

G Suite Business / Enterprise プランに含まれるローコードアプリケーション開発ツール

です!

f:id:medley_inc:20190821171328p:plain

主に以下のような特徴があります。

  • バックエンドのデータストアとして、RDB(Cloud SQL)が利用される
  • 開発言語は JavaScript をベースとしたスクリプト言語である Google Apps Scriptである
  • G Suite のサービス(ユーザーディレクトリ、メール、ドライブ等)と容易に連携が可能である
  • UIのカスタマイズの容易さと高い自由度がある

メドレーでの社内活用事例

メドレーでは、Google App Maker を活用して複数のアプリケーションを実装しています。

今回は、そのうちの一つである社内稟議システムについての概要を紹介させて頂きました。(当日はデモも実施しているので、デモの内容を見たい方はセッション動画をご覧下さい) f:id:medley_inc:20190822102114p:plain

App Maker を使ったアプリケーション開発の流れと開発Tips

App Maker はアプリケーション開発プラットフォームなので、開発の流れを以下の 3step に分割した上で、Tipsを紹介させて頂きます。

  1. データモデルの定義
  2. UI作成
  3. ビジネスロジック記述

1. データモデルの定義

はじめに、GUIベースでRDBメタデータを定義していきます。

モデル(テーブル)の主な設定項目

  • FIELDS:モデルのフィールド情報を定義
  • DATASOURCES:データベースでいうところのビューに近い概念の設定
  • RELATIONS:モデル間のリレーションを定義
  • EVENTS:クライアントのデータベース操作に対するイベントスクリプトを定義
  • SECURITY:モデルに対する権限を制御

f:id:medley_inc:20190821171355p:plain

データモデルの定義における開発Tips

  • EVENTSの挙動

    MODELの設定項目なので一見データベーストリガーと思いがちですが、このイベントは、サーバーサイドスクリプトや外部からのデータベースレコード操作では、トリガーされません。(クライアントサイドからの操作限定) サーバーサイドスクリプトや外部からの操作には、別途関数呼び出しを組み込む等の配慮が必要になります。

  • データベースへの更新反映タイミング

    既定の設定ではクライアントでデータソースの情報が変更された場合に、サーバーに即時反映される動き(Auto Save Mode)になります。この動きを止めたければ Manual Save Mode に切り替えることも可能ですが、コード記述量が大きく増えることになります。Auto Save Mode のままでも UI/UX の工夫で回避できたりするので、まずそこを検討するのが重要かなと思います。

  • 細かな権限制御

    GUI からできる権限制御設定は限られています。アプリケーション内での動的な権限制御や、フィールドの値に基づく細かな権限制御が必要な場合は、Query BuilderQuery Script による読み込み制御が必要になりますが開発コストが結構増加するので、他の回避策がないか事前に検討することをお勧めします。

2. UI作成

次に、ウィジェット(画面を構成する部品)をドラッグ&ドロップで配置して画面を作成していきます。

一般的に必要となるボタンやドロップダウンに加えて、G Suite ならではの User PickerDrive Picker 、更にはリッチなポップアップ、ダイアログ等も利用可能です。

スタイルに関しては、バリアントを利用することで、統一感のあるスタイル適用が容易に可能になっています

f:id:medley_inc:20190821171425p:plain

UI作成における開発Tips

3. ビジネスロジック記述

最後に、2種類のスクリプト(Client Script, Server Script)を利用して、ビジネスロジックを記述していきます。(アイテム生成とか、読み込みとかは基本的に記述不要)

Client Script からServer Script を呼び出したい場合は、 Google Apps Script 同様、以下のような形で実行が可能になっています。

google.script.run.ServerSideFunction();

f:id:medley_inc:20190821171501p:plain

ビジネスロジック記述における開発Tips

  • 外部公開できない

    Google Apps Script で言うところの、doGet/doPost 関数のような Web API は、App Maker のスクリプト内に作ることができないようになっています。外部システムとの連携が必要な場合、Cloud Function 等を介して、Cloud SQL を直接操作する必要があります。(トランザクション処理等は複雑化します)

  • ローカルの開発環境と上手く連携できない

    Google Apps Script で利用可能な clasp は、現時点で App Maker には対応していません。バージョン管理、デプロイ管理機能は開発コンソールに実装されていますが、コードレベルでの差分レビュー等を実施したい場合は、現時点では少しめんどくさいです。

  • 定期実行トリガーをGUIで設定できない

    Google Apps Script ではGUIから設定が可能な、「時間ベース」のトリガーがGUIで簡単に設定できません。設定が必要な場合は、以下のようなスクリプトベースで設定する必要があります。

ScriptApp.newTrigger('functionName').timeBased().at(date);

App Maker をこれから始める人向けの情報

なお、今回紹介させて頂いた内容は App Maker を全く触ったことがない人には少し難しい内容だと思っています。

知識がゼロからの方は、以下のナレッジを元に是非一度チュートリアルなどで簡単に触ってから、改めて読んで頂けると理解が深まるかと思います。

まとめ

今回紹介させて頂いた Google App Maker は、G Suite をディープに利用している企業であれば、Google Apps Script に匹敵する強力な社内アプリケーションプラットフォームになると感じています。

App Maker のようなローコード/ノーコード開発プラットフォームは既に市場にいくつか出ており、Google App Maker はその中でも比較的コーディング・技術力が求められるプラットフォームだと思います。しかし、その分既存社内システムと親和性の高い高度な自動化が実現しやすいプラットフォームでもあると思うので、臆せずにチャレンジする価値は十分にあると思います。

なお、セッション中に紹介させて頂いた稟議アプリケーションは、App Maker に対する知識が0の状態から1~2ヶ月程でSlackとの連携も含めて1人で実装できました。(RDBやGASに対する知識は、ある程度習得済みの状態が前提にはなっています)

GA直後ということもあってインターネット上のナレッジが少ない中、探り探りに得られた活用のヒントを今回の場でお話しさせて頂きましたが、引き続き App Maker というプラットフォームを上手く利用していくには、ユーザーコミュニティの盛り上がりが欠かせないと思っていますので、引き続き情報発信等を通じて盛り上げていければと考えております。

最後になりますが、メドレーではこのような市場に出て間もないテクノロジーでもチャレンジしていける風土があります。こういったチャレンジを求めている方は、ぜひご応募下さい。

www.medley.jp

www.medley.jp

Developers Summit 2019 Summerで弊社田中がエンジニアのキャリアについてお話させていただきました

みなさん、こんにちは。開発部エンジニア平木です。

少しレポートまで間が空いてしまいましたが、去る7/2(月)にソラシティカンファレンスセンターで開催されたDevelopers Summit 2019 Summerにメドレーが協賛させていただきました。

また、弊社の開発部長である田中がSI × Webの総合力で切り拓く新しいエンジニアのキャリアパスというタイトルのセッションでお話をさせていただきましたので、レポートを書きたいと思います。

会場の雰囲気

f:id:medley_inc:20190719173752j:plain
会場入口の立て看板がステキでした

会場ですがやはり今回も来場者が多く、セッション前には列が出来ていました。休憩時間中のブースにも人だかりといった感じで熱気を感じました。

f:id:medley_inc:20190719172816j:plain
次のセッション待ちで長蛇の列が
f:id:medley_inc:20190719172807j:plain
ブースも人が切れませんでした
しかしながら、運営が大変にスムーズだったので大きな混乱もなく次々と快適にセッションが見られるのは、やはり今までの経験によるものだろうなーと感じました。

印象に残ったセッション

f:id:medley_inc:20190719174247j:plain

色々とセッションを見ましたが、個人的にはやはり、@t-wadaさんのセッションは何度見ても惹き込まれるなと今回も拝見して感じました。

f:id:medley_inc:20190719173721j:plain

今回の内容を聞くと例え、全くテストを導入していないようなプロジェクトだったとしても「明日からちょっとずつやっていこう」と勇気をもらえるような内容でした。

f:id:medley_inc:20190719173729j:plain

エンジニアのキャリアパス

f:id:medley_inc:20190719173659j:plain

いよいよ、弊社田中のセッションです。残念ながら、資料は非公開とさせていただいています…。申し訳ありません。

f:id:medley_inc:20190719174601j:plain

内容としては、少し前まではいわゆるSIerとWeb系という2つの領域で結構明確に壁を感じることもあったと思います。しかし、近年X-Techなどの文脈では、関連省庁の法令やガイドラインなどを遵守しつつ、使いやすいUIへの落とし込みやマネージドサービスを使用したインフラの構築などを設計する必要があります。これらの設計の上で、Webサービスとして高速にPDCAを回しサービスを改善していくという能力も他方で必要になります。

f:id:medley_inc:20190719174328j:plain

こういった背景により、きっちりとした要件定義や設計する能力を求められるSIer的な要素と手を動かして早くサービスを改善するサイクルを回す能力が必要なWeb的な要素という、それぞれの得意領域をミックスしたエンジニアが求められているのではないかというお話をさせていただきました。

f:id:medley_inc:20190719173302j:plain

途中田中のキャリア変遷や、弊社のCLINICSを例に取り具体的にどのような能力を求められるのか?ということをお話させていただきました。

終了後のアンケートなど拝見する限り、やはり業界の括りに囚われがちなところも多いなか、キャリアパスの一つの実例として、ご好評をいただいたのは嬉しい限りでした。

まとめ

メドレーのエンジニアやデザイナーは、きっちりと法令やガイドラインを守りつつ、その概念をプロダクトの設計に落しこみ、出来るだけ早くPDCAを回し、早く確実に実装することを目指しています。Developers Summit 2019 Summerのような多種多様なキャリアの方々が来場するイベントで、このようなお話をさせていただいたのはとても有意義だったと感じています。

f:id:medley_inc:20190719173131j:plain
セッションが無事終了し、ほっと一息付きながらメドレーロゴと一緒に

▼メドレーってどんな会社?気になった方はこちら www.medley.jp

データウェアハウスとして使うAmazon Redshiftについて

はじめに

こんにちは。開発本部の阪本です。

今回は私が社内勉強会(TechLunch)にてAmazon Redshift(以下Redshift)についてお話した内容を紹介させていただきます。

Redshiftとは

概要

f:id:medley_inc:20190701165024p:plain RedshiftとはAWSサービスが提供しているデータウェアハウスで、高可用/高パフォーマンス/柔軟なスケーラビリティを実現しているのが特徴です。

競合としてはBigQueryHadoop、また同じAWSサービスではAmazon Athenaも同様の位置付けになると思います。

データベースとしての特徴

Redshiftの特徴として、列志向型データベースという点があります。

MySQLのようなリレーショナルデータベースはデータを行(レコード)単位で保持している事に対し、Redshiftは列単位で保持しています。

f:id:medley_inc:20190701165052p:plainf:id:medley_inc:20190701165052p:plain 列単位でデータを持っているため集計クエリのような特定の列に対して大量の行を精査するのが高速である反面、行を特定してのアクセスはMySQLPostgreSQLのような行志向のデータベースに比べてのクエリに比べて遅い傾向にあります。

またデータにはSQLでアクセスすることができ、構文もPostgreSQLと互換性があります。 最近スキーマレスなデータベースなどが多く出てきていますが、Redshiftは事前にテーブルを作成する必要のある従来型のRDBMSの形となっており、テーブル作成時はCREATE TABLEといったデータ定義言語(DDL)を使うことになります。

機能面の特徴

f:id:medley_inc:20190701165113p:plain:w350 先にも書きましたが、データアクセス時に使うSQLPostgreSQLの構文と互換性があります。

よってPostgreSQL用ドライバ(JDBC含む)さえ使えれば、後は特別に意識することなくRedshiftに対して接続やクエリ発行が行えるということになります。

この恩恵はプログラムだけではなく他社が展開しているサービスにも受けることができ、BIツールのTableauRedashなどもそのままデータソースとして利用することが出来ます。

次に、一般的なRDBMSとの差についてです。 RDBMSにはありRedshiftには無いものとしては - UNIQUE制約 - 外部キー制約 - インデックスが無い

などがあります。

インデックスに関しては遠い意味での代用品(Sort Key)があるものの、基本的には使うことが出来ません。 注意点としてクエリ自体はPostgreSQL互換なのでこれらを作るDDL構文を受け入れてくれるますが、Redshiftでは無視されますのでご注意ください。

逆に、Redshift固有のものとしては - Sort Key - 分散キー - 列圧縮

などがあります。 これらについては以下で少し掘り下げて説明します。

Sort Key

テーブルをソートする際に使うインデックスのようなものです。 列単位で指定することができ、ORDER BYGROUP BY句などの精査速度に影響します。

分散キー

MySQLでいうパーティショニングキーに近いものとなります。

Redshiftのデータ分散方法は - 均等に分散 - キー値による分散 - 全コピー - Auto(負荷状況による自動選択)

の4つで、データ量や特性によって使い分けることが出来ます。

分散キーはRedshiftを上記の方法でクラスタリングした際に、どのノードにどのデータを保持するかを決定する判断材料となるキーです。

運用面の特徴

AWSコンソール

f:id:medley_inc:20190701165138p:plain RedshiftはAWSコンソール上からも詳細な情報を確認することが出来ます。

f:id:medley_inc:20190701165201p:plain Amazon RDSにあるような一般的なメトリクスに加えてクエリ単位での実行状況や実行計画、そしてクエリの強制停止もコンソールから実行することができます。

データ取り込み

Redshiftはインポート元となるデータ取り込み選択肢が豊富ということも特徴の一つです。

取り込み可能な形式

CSV/JSON/AVRO/PARQUET/ORC + これらの形式を圧縮したもの(BZIP,GZIPなど)

読み取り元

Amazon S3/Amazon EMR/Amazon DynamoDBなど

特にデータ配置元としてS3がサポートされているので、各種サービスが出力するログや、Amazon CloudWatch LogsからのS3やAmazon Kinesis Data FirehoseからのS3・・など、組み合わせ次第で可能性がとても広がります。

またS3に配置しているデータはインポートせずに外部テーブルとして直接クエリを実行する機能Amazon Redshift Spectrumがあります。データ量がとても多い場合などにはこちらを利用するのも有効な手段です。

ワークロード管理

f:id:medley_inc:20190701165215p:plain 負荷に関する運用についてはWLM(Work Load Management)という機能があります。

これはRedshiftに接続するユーザをグループ単位で負荷制御を行うことが出来る機能です。

制御できる項目としては

並列クエリ実行数

同一グループ内でのクエリ同時実行数。上限に達すると待ち行列に入って詰まる。

クエリ実行時間

クエリ実行時間の上限。

メモリ使用量

クエリ実行時に使うメモリ使用量の上限。

などがあります。

可用性について

Redshiftはクラスタリングをサポートしており、クラスタにはクエリの待受を行うリーダー(Leader)ノードと実処理を行うコンピューティングノードが作成されます。

AWSも推奨しているように、Redshiftはマルチノード運用を基本としています。

これはRedshiftの個々のデータノードはRAID5のような形で各ノードに分散しているため、ノード障害が発生した場合でも生存ノードからノード復旧を自動で行ってくれます。 (同時に障害が発生しても復旧可能なノード数については、クラスタ内のノード数に依存します)

将来性について

過去1年半の間でもこれだけの新機能が追加されており、まだまだ進化しています。

  • UNLOADコマンドのCSV対応
  • Concurrency Scaling
  • ALTER文でVARCHARの桁数変更
  • Elastic Resize
  • UNLOADコマンドのヘッダ行出力対応
  • コンソールにてクエリ実行環境追加
  • ネスト化されたデータのサポート
  • 自動バージョンアップ方式の設定/予告確認可能
  • Parquet、ORCからのIMPORTサポート
  • Amazon Redshift Spectrum東京サポート
  • 新ノードタイプDC2
  • Query Editorの追加
  • PL/SQL プロシージャのサポート
  • Vacumコマンドの自動化 New!!(2018/12リリース)
  • WLMワークロード管理の自動化 New!!(2019/06リリース)

実際の使い勝手

では、実際のところRedshiftの使い勝手がどういったものなのかを実例を含めて紹介します。 ここではdc2.large ノード数2のサンプル環境を使用します。

データのロード

クエリを発行するにも、まずは元になるデータが必要です。

ここでは日本語Wikipediaの目次ダンプデータを100セット分用意し、その内容をRedshiftにロードしてみます。

f:id:medley_inc:20190701165252p:plain f:id:medley_inc:20190701165257p:plain まずは目次データをこちらの画像の様に加工し、100セット分のファイルとして分割しS3へとアップロードします。

f:id:medley_inc:20190701165317p:plain 今回のロードするデータ量は235,732,000レコードの11.9GBとなりました。

f:id:medley_inc:20190701165331p:plain S3にファイルが配置出来たら、それを格納するテーブルをRedshiftに作ります。 この際PostgreSQLCREATE TABLEによってテーブルを作成します。

f:id:medley_inc:20190701165355p:plain テーブルの作成が完了したら、次はデータのロードです。 これもSQLクエリのCOPYコマンドによって取り込みが行われます。 今回このロード処理は8分55秒で完了しました。

データ量から考えるとかなり早いと感じますが、これはロード処理において並列処理の恩恵を最大限に受けているということが理由と考えられます。

Redshiftのロード処理は分割されたファイルを使って並列処理を実行するため、巨大な単一ファイルを取り込むより短時間で取り込むことができます。

クエリ発行

次に、クエリ発行についてですが、これはそのままPostgreSQLのクエリを実行することになります。

今回は先のステップで取り込んだ目次ページをタイトルごとにDISTINCTする集計クエリを発行してみます。

f:id:medley_inc:20190701165409p:plain すると49秒で結果が帰ってきました。 最低限のスペックで235,732,000レコードを精査するクエリの実行時間としては良いスコアではないでしょうか。

不便に感じたこと

ここでは私がRedshiftを運用していて不便に感じた事をいくつか紹介します。

料金が高い

これだけの機能とスペックが含まれているので仕方が無いかもしれませんが、AWSの他のサービスと比較して高価な印象があります。

さらにマルチノードとなると料金が掛け算で増えることになり、スペックの選択肢が他のサービスと比べても少ないため運用の際にはよく見積もりされることをおすすめします。

更新クエリが遅い

列志向型のせいなのかランダムアクセスが苦手で、特定の行を探して更新するUPDATEDELETEは遅いです。

そもそもRedshiftは頻繁にUPDATE/DELETEする用途には向いておらず(後述)、INSERTのみの積み上げ型や全レコード洗い替えが基本の用途になります。

また、UPDATE/DELETEを繰り返すとパフォーマンスが低下します。

これは内部的に保持しているSortKeyの状態が更新するたびに劣化し、連動してパフォーマンスが低下するためです。

解消するためにはSortKeyの再構築(VACUM/OPTIMIZEコマンド)により回復しますが、そもそもコマンド実行時間が長く、負荷も大きいので実行タイミングは検討が必要となります。

(追記)2018/12のアップデートで自動実行機能が追加されました!

AWSコンソールが機能しないことがある

先に多くの便利な機能を紹介しましたが、なぜかこれらがAWSコンソール上で機能してくれないことが割とあります。

WLMの設定次第なのか不明ですが、実行中のクエリが出なかったりクエリの強制停止が効かないなど、イザという時に限って使えないことがよくありました。

メンテナンスが高頻度

新機能が続々追加されていると紹介していますが、この度にメンテナンスが発生するものとなります。

タイミングは事前に設定したメンテナンスウインドウの週一の曜日/時間帯ですが、経験から2週間に1度ぐらいの頻度で発生していました。

この時間帯は再起動を伴う場合もあるため、WriteどころかReadすら出来ない状態になることもあります。

そのため日中は社内業務。夜間はバッチでといった24時間ずっと稼働する要件を満たす事は少し厳しいものとなります。

まとめ

まとめととなりますが、Redshiftは特徴をふまえると下記のような場面で利用すれば良いかなと感じています。

BIツール等のデータソースとして

メンテ頻度や負荷の問題があるので、自分達のアプリから直接は繋げない。

履歴やマスタデータのような大量の積み上げ型データの集計

UPDATEが発生するなら、全件入れ替えが可能なデータ。

1日の利用頻度がそれなりにあること

頻度が高く無いのであれば、Athenaの方が安い。

どのサービスにも言えることですが、要件の合ったサービス選びをすることが一番大事です。

Redshiftについても特徴がはっきりしているタイプのサービスなので、使い所を間違えないように、上手く使っていければと思います。

メドレーが協賛予定のイベントをご紹介します。(2019/7~)

こんにちは。開発本部エンジニアの平木です。

メドレーでは、技術や業界の発展に少しでも寄与できればという考えから、エンジニア・デザイナーの技術イベントなどに、積極的に協賛させていただきたいと考えています。7月以降のイベントも積極的にスポンサードさせていただきますので、ぜひ皆様にもお越しいただきたく、このエントリではメドレーが協賛するイベントの魅力をご紹介します。

Developers Summit 2019 Summer

f:id:medley_inc:20190620190529p:plain

  • 公式サイト
  • 2019/07/02(火) @ソラシティカンファレンスセンター
  • ブロンズスポンサー

一番最初にご紹介するのは、ご存知Developers Summit 2019 Summer(以降デブサミ夏)です。

本家であるDevelopers Summit 2019冬でも協賛させていただきましたが、今回のデブサミ夏ではブロンズスポンサーとして執行役員である田中SI × Webの総合力で切り拓く新しいエンジニアのキャリアパスというタイトルでお話します。

ここ数年でX-TechDXの必要性が一気に叫ばれるようになってきましたが、メドレーでも医療におけるデジタルトランスフォーメーションの推進を目指して日々プロダクトの開発を進めています。X-TechやDXを推進する上で、いわゆる「Web系エンジニア」と「SI系エンジニア」という垣根を越えた、ハイブリッドな新しいエンジニア像が求められるようになってきたと感じます。「課題を解決するために必要とされるようになったハイブリットな能力とは?」「これからのエンジニアはどう成長していくのがよいか?」ということをお話させていただきます。

おかげさまで、現時点でセッションは満員になっていますが、ぜひご覧いただければ幸いです。

CloudNativeDays Tokyo 2019 / OpenStack Days Tokyo 2019

f:id:medley_inc:20190620190716p:plain

今年はイベントの統合もされ、名称も一新された日本最大級のコンテナ技術を始めとしたクラウドネイティブとオープンインフラの祭典である、こちらのイベントにも協賛させていただきます。

当日会場で配られるトートバッグに公式ロゴと共にメドレーのロゴを入れていただきました。実際にどんなデザインになるかは当日にご来場していただくまでのお楽しみとさせていただきますが、とても良いものになっているかと思います。

builderscon tokyo 2019

f:id:medley_inc:20190620190740p:plain

2016年から毎年開催されている、色々な分野のエンジニアの様々なセッションが一気に聞けるイベント「builderscon tokyo」ですが(去年は電子名札バッジがインパクトありましたね)、今年は初めてスポンサーとして参加させていただくことになりました。

会場である東京電機大学千住キャンパスの部屋の一つ、100周年記念ホールでセッションするスピーカーさんの後ろに設置されるバックパネルのなかに、メドレーのロゴが入ることに。

こちらのイベントでは弊社エンジニアもお邪魔する予定ですので、会場でお気軽にお声がけしていただければと思います。

CODE BLUE 2019

f:id:medley_inc:20190620190759p:plain

今年で7回目の開催となる情報セキュリティの国際会議「CODE BLUE 2019」に初めてスポンサーをさせていただいています。

メドレーでも取り扱っている情報の重要性から、会社としての取り組みでISMS認証 / ISMSクラウドセキュリティ認証を取得していますが、このようなセキュリティに関するイベントにも業界の発展に少しでも寄与できればと今年から協賛させていただくことになりました。

DesginShip 2019

f:id:medley_inc:20190620190818p:plain

去年から開催されているデザインカンファレンス「DesignShip 2019」に、去年から続きスポンサーをさせていただきます。

今年は会場も東京国際フォーラムになるということで、メドレーも去年よりもさらにアクティブな形でイベントに参加させていただくことになりそうです。

まとめ

ここまでご紹介させていただいたイベント以外にも現在、スポンサーの打診をさせていただいているイベントがいくつかありますが、こちらも決定次第おしらせできればと考えています。

メドレーでは、技術や業界の発展に少しでも寄与できればという考えから、エンジニア・デザイナーの技術イベントなどにこれからも積極的に協賛させていただくスタンスを取っています。

全てのイベントに協賛できるわけではありませんが、スポンサーを探しているイベント運営者の方がいらっしゃいましたら、一度お気軽にお問い合わせいただければと思いますので、よろしくお願いします。

▼メドレーってどんな会社?気になった方はこちら www.medley.jp

ユーザー認証とOpenID Connect

こんにちは。開発本部のエンジニアの鶴です。 今回は先月に行った社内の勉強会TechLunchの内容をご紹介させていただきます。

イントロ

Webサービスでは、ユーザーにアカウントを作ってもらい、ログインをしてサービスを利用してもらう、というユーザー認証を利用するサービスも多いかと思います。 Webサービスを開発する側としては、サービスごとに都度ユーザー認証の仕組みを構築する必要がありますが、セキュリティ対策の観点から考慮することが多く、地味に開発の工数がかかってしまいます。

 

また最近では、Amazon CognitoFirebase AuthenticationAuth0など、ユーザー認証サービスがいくつかリリースされ、ユーザー認証の機能をこれらの外部サービスに任せて開発の手間を省くという選択肢も取れるようになってきています。 自分自身、かつて担当したプロジェクトでユーザー認証の仕組みをAmazon Cognitoにまかせてシステムを構築したことがありました。

しかし、当時は特にユーザープールの機能がリリースされて間もないこともあり、SDKの動作やサービスの仕様の理解にかなり手間取ったことを覚えています。

ユーザー認証サービスではOpenID Connectという仕様に準拠していることが多いのですが、おそらく自分にとってこの仕様の理解が疎かだったことが原因の一つだったと思います。

 

そこで今回は、ユーザー認証とOpenID Connectの仕組みについて改めて勉強し直したので、その内容を簡単に解説をさせていただこうと思います。

ユーザー認証とは

ユーザー認証の前に、そもそも認証とはどういう操作のことを指すのでしょうか。 みんな大好きWikipedia先生によると、以下のような記載があります。

 

認証(にんしょう)とは、何かによって、対象の正当性を確認する行為を指す。 認証行為は認証対象よって分類され、認証対象が人間である場合には相手認証(本人認証)、メッセージである場合にはメッセージ認証、時刻の場合には時刻認証と呼ぶ。 単に認証と言った場合には相手認証を指す場合が多い。

 

ユーザー認証はWebサービスにとってリクエストを送信してきた相手の正当性を認証することなので、相手認証の1つですね。 さらに相手認証の認証方法として2通りの方法があります。

 

第1の方法は、被認証者が認証者に、秘密鍵をもっていることによって得られる何らかの能力の証明を行う方法である。第2の方法は、被認証者が認証者に、被認証者の公開鍵に対応する秘密鍵の知識の証明を行う方法である。

 

ユーザー認証の場合、多くはこの第1の方法での認証で、ログイン時にユーザーIDに加えて、この「秘密鍵」としてアカウント作成時に登録しておいたパスワードを入力することでユーザー認証を行っているかと思います。

Webサービスでのユーザー認証

Webサービスで扱う情報の秘匿性が高くなればなるほど、この「秘密鍵」が本当にそのユーザーにしか提供できない情報であることが求められます。

上述のようなパスワードによる認証の場合、パスワードが推測されるなどして悪意のある第三者にアカウントが乗っ取られてしまう事件はよく耳にします。

よりセキュリティを高めるため、パスワード以外の認証や多要素認証などを用いる事が増えてきました。

 

また、セキュリティの観点だけでなく利便性の観点からも、パスワード入力の代わりに指紋認証や顔認証によるログインや、あるいは各種SNSアカウントによるログインも増えてきています。自社の複数のサービスを連携できるようユーザーに共通IDを提供したい、といったケースもあるかもしれません。

 

最近ではパスワードレス認証やWebAuthnも注目されていますね。今回は紹介は割愛しますが、パスワードレス認証の一つであるFIDO認証は、前述の「被認証者が認証者に、被認証者の公開鍵に対応する秘密鍵の知識の証明を行う方法」を利用した認証方式のようです。(ref1, ref2

 

このように、セキュリティの観点やユーザー利便性の観点などにより、Webサービスにおけるユーザー認証機能は1回作ったら終わりではなく、時流に応じて適宜改修する必要が出てくることもあるかと思います。

 

しかし、特にユーザー認証がメインのサービスと密結合している場合などでは、認証の前後など認証処理そのものだけでなくその周辺の処理への影響範囲も無視できない場合もあり、ユーザー認証の改修に工数が思ったよりかかってしまったり、対応が滞ってしまうこともあるかもしれません。

 

そんなとき、認証サービスをメインのサービスと切り離すことでより柔軟なユーザー認証手段を提供できるよう、OpenID Connectの導入を検討してみても良いかもしれません。

OpenID Connectとは

OpenID Connect(以降、OIDC)について、本家サイトでは以下のように説明されています。

 

OpenID Connect 1.0 は, OAuth 2.0 プロトコルの上にシンプルなアイデンティティレイヤーを付与したものである. このプロトコルは Client が Authorization Server の認証結果に基づいて End-User のアイデンティティを検証可能にする. また同時に End-User の必要最低限のプロフィール情報を, 相互運用可能かつ RESTful な形で取得することも可能にする.

この仕様は, OpenID Connect の主要な機能である OAuth 2.0 上で End-User の情報伝達のためにクレームを用いる認証機能を定義する. この仕様はまた, OpenID Connect を利用するための Security, Privacy Considerations を説明する.

 

日本語, 英語

 

個人的には、メインのサービスと認証サービスを切り離して運用することを想定して仕様が規定されている点が重要と考えます。 OIDCを利用することで、ユーザー認証をより柔軟に改修したり新しい認証方法に対応したりすることがしやすくなることが期待されるからです。

 

なお、OIDCの仕様には認証手段自体(パスワード認証や多要素認証など)に関しては規定されておらず、あくまで認証サービスによる認証結果の取得方法や扱い方についてが規定されています。

また、様々なユースケースに対応できるよういくつかの処理フローやオプショナルな設定が提供されていますが、その反面セキュリティの確保は実装者に委ねられており、ユースケースに応じて適切な実装を行う必要があります。

 

前述したユーザー認証サービスであるAmazon CognitoやFirebaseAuthenticationなどは、認証手段が標準でいくつか提供されており、加えてバックエンドとSDKにOIDC固有のセキュアな実装が施されてあるため、開発者は最小限の設定だけでユーザー認証機能が利用できるようになります。便利ですね。

処理フローの解説

さて、OIDCの具体的な処理について解説していこうと思います。


まず登場人物です。

  • OpenID Provider(OP):認証認可を行うサービス。ユーザー認証情報(識別子やパスワードなど)を管理したり、認証に関するユーザー属性情報(氏名やユーザー名など)を保持する。
  • RelyingParty(RP): アクセス元のユーザーの認証とユーザー属性情報を要求するサービス。ユーザーからのリクエストに対しOPによる認証結果を信頼(rely)してリソースへのアクセスを許可する(例えばマイページを表示するなど)。
  • EndUser:ログインをしてサービスを利用しようとしているユーザー。

 

基本的な用語も先に簡単に紹介しておきます。

  • クライアントID:OpenID Providerで管理する、RelyingPartyの識別情報。
  • クライアントシークレット:OpenID ProviderがRelyingPartyごとに発行する秘密鍵
  • 認証コード:後述するAuthorizationCodeFlowでOpenID Providerが発行する短命のパスワードのようなもの。
  • IDトークン:OpenID Providerから発行される、ユーザーによる認証を行った証明情報。JSON Web Token(JWT)で表現され、検証により改ざん検知することができる。認証の内容(OpenID Provider、ユーザー識別子、RelyingPartyのクライアントID、有効期限など)やユーザー属性情報が格納される。
  • アクセストークン:OpenID Providerが保持するユーザー属性情報に対しアクセスするためのOAuth2の認可トークン。

OIDCの処理フローは大きく分けて3種類が規定されています。

  • AuthorizationCodeFlow:認証成功時にOpenID ProviderがRelyingPartyに対し認証コードを発行し、RelyingPartyはこれを用いてOpenID ProviderからIDトークン等を取得する。RelyingPartyがサーバーサイドアプリケーションで、OpenID Providerから発行されるクライアントシークレットを安全に管理することができる場合などに用いられる。
  • ImplicitFlow:認証コードを使わず認証結果のレスポンスでIDトークン等を取得する。RelyingPartyがクライアントアプリケーションの場合など、クライアントシークレットが安全に管理できない場合などに用いられる。
  • HybridFlow:AuthorizationCodeFlowとImplicitFlowの組み合わせ。

これらのフローの違いは以下の表のとおりです。

 

f:id:medley_inc:20190426141901p:plain

公式より引用

 

今回は、公式こちらの解説記事などを参照しながら、基本の処理フローであるAuthorizationCodeFlowについて解説します。

 

簡略化のため、イメージ重視で登場人物は「ユーザー」「(ユーザーにサービスを提供する)Webサービス」「認証サービス」と表現することにします。

f:id:medley_inc:20190426141939p:plain

大まかには以下のステップで処理が行われます。

  1. ユーザーからのアクセスに対し、Webサービス認証サービスにユーザー認証を要求する
  2. 認証サービスはユーザー認証を行い、認証コードを発行して、ユーザーWebサービスにリダイレクトさせる
  3. Webサービスは2で取得した認証コードを用いて認証サービスにIDトークン等をリクエストする
  4. Webサービスは3で取得したIDトークンを検証し、ユーザーの識別子を取得する

Step.0 : 事前準備

あらかじめWebサービス認証サービスからクライアントIDとクライアントシークレットを取得し保持しておきます。

f:id:medley_inc:20190426142007p:plain

Step.1: ユーザー認証の要求

ユーザーWebサービスに対し一般的なログインの流れでログインを要求すると、Webサービス認証サービスにリクエストをリダイレクトします。

f:id:medley_inc:20190426142502p:plain

Webサービスから認証サービスへのリダイレクトのURLは以下のような感じです。

HTTP/1.1 302 Found
Location: https://server.example.com/authorize?
   response_type=code
   &client_id=s6BhdRkqt3
   &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
   &scope=openid%20profile
   &state=af0ifjsldkj

 

response_type でOIDCのどの認証フローを使うかを指定します。

redirect_uri は、認証サービスでの認証が成功したときのWebサービスにコールバックするURLです。これは事前に認証サービスに登録しておく必要があります。

scopeには認証の内容を設定します。openidは必須で、他にはOAuth2のアクセストークンを使って取得できるユーザー属性情報を指定します。

scopeで指定できるユーザー属性情報は以下のとおりです。

 

f:id:medley_inc:20190426142232p:plain

公式より引用

 

ユーザーの認証でよく使われそうな「氏名」や「メールアドレス」など基本的な属性情報が定義されています。

 

state はCSRF対策などのためのランダム値です。認証フローを開始するたびにWebサービスが発行し、リクエストとコールバックの間で値が維持されます。

 

他にもいくつかのパラメータ(nonce など)が定義されており、必要に応じて利用します。

Step.2: ユーザー認証と認証コードの発行

認証サービスでは認証手段に応じてログインID・パスワードの入力フォームなどを表示し、ユーザーから認証情報を取得して認証処理を行います。

f:id:medley_inc:20190426142212p:plain

認証サービスはユーザーの認証に成功すると、認証コードを発行し、ユーザーWebサービスにリダイレクトさせます。

 

HTTP/1.1 302 Found
Location: https://client.example.org/cb?
   code=SplxlOBeZQQYbYS6WxSbIA
   &state=af0ifjsldkj

 

リダイレクト先について、認証サービスはStep.1で受け取った redirect_url を認証サービスに予め登録されているURLと合致することを検証する必要があります。Webサービスのなりすましを防ぐためです。

またWebサービス側で認証サービスからのレスポンスであることを確認できるよう、state もパラメータに含めます。

 

なお、認証に失敗した場合は下記のように認証エラーした内容をパラメーターに加えてWebサービスにリダイレクトさせます。

HTTP/1.1 302 Found
Location: https://client.example.org/cb?
   error=invalid_request
   &error_description=
     Unsupported%20response_type%20value
   &state=af0ifjsldkj

Step.3: 認証結果の取得

Step.2 でWebサービス認証サービスからのリダイレクトを受け、認証コードを取得すると、この認証コードを利用して認証サービスに対して認証結果情報(IDトークンなど)を取得します。

f:id:medley_inc:20190426142612p:plain

Webサービスから認証サービスへの認証結果取得リクエストは以下のような形式になります。

 

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
 
grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
  &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb

 

認証コードを送信する必要があるため、POST メソッドでリクエストします。またクライアントIDとクライアントシークレットによるBASIC認証を行います。

このリクエストでクライアントシークレットが必要になるのですが、これは認証サービスにとってWebサービスの正当性を検証するための重要なパラメータであり、安全に管理される必要があります。

SinglePageApplicationのようにユーザー側にあるアプリケーションでOIDCを処理する場合には、このクライアントシークレットが安全に管理される保証がないため、AuthenticationCodeFlowではなくImplicitFlowなどを利用する必要があります。

 

Webサービスからのリクエストを受け取った認証サービスは grant_type にStep.1で指定した処理フローに該当する情報を渡し、認証コード( code )と合わせて認証サービスにリクエストの検証をさせます。

認証サービスはリクエストの検証に成功すると、Webサービスに対し認証結果としてIDトークン等を返却します。

 

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-cache, no-store
Pragma: no-cache
 
 {
  "access_token":"SlAV32hkKG",
  "token_type":"Bearer",
  "expires_in":3600,
  "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
  "id_token":"eyJ0 ... NiJ9.eyJ1c ... I6IjIifX0.DeWt4Qu ... ZXso"
 }

 

access_token は認証サービスで管理しているユーザー属性情報を取得するためのOAuth2トークンです。

refresh_tokenは認証サービスからaccess_tokenを再発行する際に利用します。

Step.4: 認証結果の検証

Webサービス認証サービスから取得したIDトークンを検証します。IDトークンは前述の通りJWTで表現されており、認証サービスの公開鍵を用いて検証することができます。

手順は こちら をご確認ください。他にも参考リンクを紹介しておきます。

下記はIDトークンに含まれる認証情報の例です。

 

{
  "iss": "https://server.example.com",
  "sub": "24400320",
  "aud": "s6BhdRkqt3",
  "exp": 1311281970,
  "iat": 1311280970
}

 

このうち sub が認証サービスで管理されているユーザーの識別子です。

iss認証サービス、audはWebサービスのクライアントIDになります。

exp、iatはそれぞれ認証の有効期限と認証したタイムスタンプです。

 

WebサービスはIDトークンが正しい内容であることが確認できれば、これをログインセッションと紐づけて保管します。

以上で認証処理は完了です。

ユーザー属性情報の取得

ユーザー認証後、Webサービスがユーザー名などのユーザー属性情報が必要になった場合、Step.3 で取得した access_token を利用し認証サービスに対してユーザー属性情報をリクエストします。

 

GET /userinfo HTTP/1.1
Host: server.example.com
Authorization: Bearer SlAV32hkKG

 

このリクエストにより、Step.1の scope で指定したユーザー属性情報が取得できます。

まとめ

以上少し長くなりましたが、ユーザー認証とOpenID Connect、特に基本のAuthenticationCodeFlowについて解説しました。限られた発表時間の中での解説のため厳密さより雰囲気を重視した内容となりましたが、お気づきの点などあればお知らせいただければと思います。

 

サービスの要件やフェーズによってOIDCを取り入れるかどうかは様々ですが、ユーザー認証の実装を自前で実装、メンテナンスしていくだけでなく、Amazon Cognitoなどの便利な認証サービスを利用していくことも選択肢の一つとして検討してみても良いかもしれません。

 

そしてそれら便利な認証サービスをうまく使いこなすためにも、その背景にあるOIDCの仕様や思想、そもそも認証の仕組みについて立ち返ってみると、理解が一段と深まるかとおもいます。

www.medley.jp

www.medley.jp

RubyKaigi 2019にメドレーがBreakfast Sponsorとして参加しました

こんにちは。開発本部のエンジニア・新居です。

メドレーは4/18〜4/20に開催されたRubyKaigi 2019にBreakfast Sponsor(朝食スポンサー)として協賛させていただきました(一昨年のRuby Sponsor昨年のLightning Talks Sponsorに続き、3年目の協賛です)。
2017年のレポート
2018年のレポート
2019年は福岡県の福岡国際会議場での開催でした。会場に向かう途中の博多駅ではさっそくRubyKaigiのポスターに迎えられ、RubyKaigiムードが高まっておりました。

RubyKaigi

博多駅ではさっそくRubyKaigiのポスターがお出迎え
ということで、今年RubyKaigiの様子をレポートさせていただきます。

Breakfast Sponsorの様子

今回はBreakfast Sponsorとしての協賛で、RubyKaigi2日目と3日目の朝8時30分から10時までの時間帯で、RubyKaigiに参加されるみなさんに朝食をご提供させていただきました。
 
朝食会場は福岡国際会議場内の1Fにあるレストラン ラコンテさん。朝食の内容はビュッフェ形式で、焼き魚やオムレツなどの定番おかずと、福岡名産の辛子明太子や辛子高菜をたらふく食べられる朝食でした。

入り口でみなさんをお出迎えするエンジニア稲本

おしゃれなテラス席

ビュッフェに並ぶおかず

フルーツもたくさん

「辛子明太 & 辛子高菜」乗せごはん

福岡名産の辛子明太子と辛子高菜を白ごはんに添えてたらふくいただきました

会場の様子、大盛況でした

テラス席はグローバルな感じ


Twitterでも朝食の様子を話題にしていただけたりと、ご満足いただけた様子が伺えました。
ご来場いただいた人数は、RubyKaigi2日目(朝食1日目)は379名、3日目(朝食2日目)は411名でした。
 
朝食会場の出入り口でご案内していると「美味しかったです、ありがとうございました!」というお声を直接いただけたりと、みなさんにご満足いただけたようで良かったです。
 
Breakfast Sponsorでの参加は初めてでしたが、みなさんが満足気に朝食会場を後にする姿を見ているとこちらも嬉しい気持ちになりました。
 
朝食をご利用いただいたみなさん、本当にありがとうございました。
 
今年はBreakfast Sponsorという形でしたが、RubyRubyコミュニティの発展のため、今後も様々な形で貢献していければと思います。

RubyKaigi 2019の様子

今年も毎年恒例のMatzさんのKeynoteから始まりました。
今年は「The Year of Concurrency」というテーマで、Ruby 3についての発表でした。
 
Ruby 3のStatic Analysis、Performance、Concurrencyあたりの話を中心に、Rubyの今後の展望について語られました。普段Rubyを使って仕事をしている身として、MatzさんからRuby 3の話を聞けたのは貴重な時間でしたし、改めてRubyの進化を実感できるセッションでした。

MatzさんのKeynote

その他のセッションスケジュールについてはこちら。

2階にはブースゾーンがあり、セッションの合間にはたくさんの参加者で溢れかえっていました。

ブースゾーンは大盛況

ブースゾーンの出入り口付近には各社のノベルティ

Ruby関連書籍の展示も

会場5階(最上階)にはハックスペースが用意されていました。
ここで各々休憩したり、黙々と作業したり、仲間と談笑したりと、様々な用途に使われていました。

ハックスペース入り口

ハックスペースの中(このときはセッション中だったので空いてました)

福岡開催ならではの屋台スペースも用意されていました。
ランチタイムには屋台ラーメンなどが振る舞われ、めちゃくちゃ混み合っていましたが、こういう地域特有の催しはRubyKaigiを盛り上げてくれるので良いですね。

ランチ前になるとゾロゾロと人集りが

ランチタイムの屋台は大行列

屋台でラーメンを食らう参加者を羨むエンジニア中畑


メドレーブースの様子

また、2階のブースゾーンにはメドレーのブースも出展しました。

今回参加したメンバー全員で
ノベルティーにはメドレーロゴ付きのうちわ、ステッカー、お水、そして恒例の絆創膏を用意しました。
 
RubyKaigi 2018でもらったメドレーの絆創膏が、子供が怪我したときに役に立ったよ〜という嬉しいお声をいただいたりもしました。
靴擦れや擦り傷を負ったとき、お子さんが転んだときとかに役に立つので、今度見かけた際はぜひお持ち帰りください。

メドレーの絆創膏
ブースではメドレーの会社説明やメドレーが提供するサービスの説明などを行いました。
 
スポンサーとして初参加だったRubyKaigi 2017に参加したときよりもメドレーのことを知っている人が増えているなあと実感しました

ブースで対応するエンジニア達(中畑、稲本、橋本)

Matzさんにも来ていただきました!

福岡の様子

そして福岡といえば美味しいごはんですよね。
 
1日目の夜はRubyKaigi 2019 Official Partyが開催され、中洲川端商店街を半貸切にして日本酒やうどん、ラーメンや地鶏などが振る舞われました。

RubyKaigi 2019 Official Partyの会場・中洲川端商店街のGuide Map

大樽に入って日本酒が配られてました

日本酒のラインナップ

f:id:medley_inc:20190424143021j:plain

うどんを前に満面の笑みの広報・深澤

夜は福岡の美食を求めて街に繰り出しました。

絶品イカの活造り

定番モツ鍋

出汁が最高の水炊き

会場近くの某有名ラーメン店のきくらげラーメン

あまりのうまさに昇天するエンジニア中畑

また、RubyKaigi初参加の2017年から続けている神社参拝にも行ってきました。
今回は警固神社(けごじんじゃ)に参拝してきました。
 

警固神社入り口

参拝するエンジニア中畑


さいごに

2017年から3度目となるRubyKaigiの協賛の様子をお届けしました。
 
Breakfast Sponsorとして、RubyKaigi参加者のみなさんにご満足いただけて本当に良かったなあと思います。
繰り返しになりますが、RubyRubyコミュニティの発展のため、今後も様々な形で貢献していければと思います。
 
来年2020年は長野県松本市での開催ということで、またみなさんとお会いできることを願って、レポートを締めたいと思います。

rubykaigi.org

お知らせ

メドレーでは医療業界に存在する課題にITを駆使して取り組んでいきたいメンバーを、デザイナー・エンジニアを中心に全職種絶賛募集中です。皆さまからのご応募お待ちしております。

www.medley.jp