社内勉強会開催レポート(OAuth 2.0とOpenID Connect | 地図情報システム)

キャディでエンジニア採用を担当しております片渕です。

今回は、エンジニアの社内勉強会「STUDDi」にてプレゼンがありました一部の情報(2ネタほど)を、レポート形式でお伝えしたいと思います。

STUDDIは、エンジニア全員が持ち回りで発表機会があるものですが、入社してくる方も増えてきたこともあり

  • まだ一度もスピーカーになっていない方(新しく入られた方)の発表する場として優先する
  • 好きな技術について思う存分語ってOK

という方針でやっております。

OAuth 2.0とOpenID Connect

今回はまず2022年1月18日に開催された社内勉強会、先山からのプレゼン内容をまとめております。

https://speakerdeck.com/caddi_eng/20220118-sakiyama-oauth2-dot-0-and-oidc-falsekohi

認証と認可の違い

先山:

今回のアジェンダとしては認証・認可の話から、OAuto2.0やOpenID Connect、アクセストークンや認可リクエストについて、説明していきたいと思います。

まず、認証と認可の違いから。

認証とは通信先の相手が誰かを確認するところで、あなたは誰?を証明するためにログインするところを指しています。

一方で認可とは、権限があるかどうかを確認していまして、決裁できるとか特定の画面を閲覧できる権限とかですね。

今回のメイントピックはこの「認可」の話になりまして、最近だとマイクロサービスが流行り、認証や認可をどうしていくかは、アーキテクチャ的には重要になってきています。

OAuto2.0とは?

先山:

認証や認可に関するプロトコルとサービスについてはスライドにある通りなのですが、その中でまずOAuth2.0を取り上げてみたいと思います。

こちらは認証ではなく認可のフレームワークで、アクセストークンを使ってAPIアクセスするための権限を委譲することができるものです。ざっくりいうとアクセストークンの発行手順を策定したものです。

注意点として、2.0の内容ではセキュリティ対応が不十分なものがあります。これは後にOAuth2.0 Security Best Current Practiceの方で補完されています。もしOAuth2.0のドキュメントを読む場合はこの点に注意してください。

現在、仕様策定中のOAuth2.1ではOAuth2.0とSecurity Current Best Practiceの内容を合体させたような仕様となる見込みです。

OpenID Connectとは?

先山:

OpenID Connect(OIDC)とは、OAuth2.0を拡張して作成されたフレームワークです。

OpenID Foundationが推進しています。ざっくり説明すると、アクセストークンに加えてIDトークンを発行する手順が書かれた仕様です。

最近、話題になっているトピックとしては、FAPI(Financial-grade API)という金融サービスに適応したものや、CIBA(Client Initiated Backchannel Authentication flow)とよばれる、何かのサービスが権限を要求してきた際に、そのサービス利用端末ではなく他の端末に権限を与えてもいいかどうかを通知してくれるものです。また、最近はeKYCも注目されています。

Kleinでの認可・認証プロセスのフローについて

先山:

認可リクエストはちょっとややこしいので、リクエストにアクセストークンを設定してリソースサーバーにアクセスする方法を説明します。

ここでは、過去のtech Blogでも取り上げられているCADDIのプロダクトの1つであるKleinを取り上げて、認可・認証プロセスのフローを解説していきます。この図は今回の説明用に簡易的にしてあります。

まず、ユーザーがログインした時に認可リストを出し、認可サーバーはレスポンスとして認可コードを返します。

認可コードをAuth0の/oauth/tokenへリクエストし、そのレスポンスに含まれたトークンを使ってBFFにアクセスすることが可能になります。

アクセスしたいサーバーにAPIでリクエストする時に使うものが、アクセストークンとよばれるもので、JWT(Json Web Token)という形式になっています。

Authorizationヘッダーの中身

先山:

JWTの中身はピリオドで区切られた3つのセクションに分類されます。先頭はヘッダー情報で、次にペイロード、最後に署名です。主に皆さんが参照するのはペイロードだと思います。ここがトークンの本文になります。認可サーバーが設定した値がここにセットされます。

署名はヘッダとペイロードをピリオドで繋げた文字列を署名処理した値が入ります。認可サーバーで秘密鍵により署名されたものなので、BFFサーバーは公開鍵でデコードすることで、認可サーバーから正規に発行されたものだと確認することができます。

上図で説明すると、リクエストに含まれたアクセストークンをBFFサーバーが検証します。先程言った公開鍵はJWKSという認可サーバーのエンドポイントから取得することができます。

デコードが成功したらBFFサーバーはトークンの中身をチェックします。例えば、有効期限が切れていたら401を、権限が足りなかったら403を返すことになります。

認可リクエストの流れ

先山:

authorizeというパスが認可サーバー側にあり、クライアントはいくつかのクエリパラメータを設定してリクエストします。

青字の部分はセキュリティ関連のパラメーターです。後ほど説明するPKCEで一部紹介をします。黄色の部分は認可リクエストの方法や手順を表すパラメーターになっています。

response_typeがトークン取得のフローを定義します。codeを指定するのが最もよくあるユースケースです。それをAuthorization Code Flowと言います。それ以外にもtokenを指定するImplicit Flowがあるのですが、これは非推奨なので使わないでください。

また、Hybrid Flowというのもあるんですが、これはユースケースが特殊なので説明は省きます。

response_modeは認可コードをレスポンスのどこに詰めてクライアントに返却するかを指定します。今回はqueryなのでクエリパラメータに認可コードが設定されます。

redirect_uriは認可サーバーにアクセスした後に戻るURLを指定します。scopeは欲しい権限を指定するパラメーターです。例えば決済APIにアクセスする権限が必要な場合はscopeにpaymentを指定する、といった使われ方です。

認可リクエストについて説明をしましたが、実際にこの辺りの開発をするときは、どのような種別のアプリケーションが認可サーバーにアクセスするのかで考慮するべきポイントが変わってきます。

ただし、OAuth0を使うのであれば、それにあったライブラリを使えばいいので、あまり考えなくてもokです。

悪意のある乗っ取り攻撃を防ぐために

先山:

ここでPKCEという仕組みについて説明します。

これはある攻撃の対策として、OAuth2.0で追加された仕様です。Auth0 SDKを利用していると目にすることがあると思いますので、説明します。

PKCEは、ピクシーと読みますが、これが利用されるようになったのは、ネイティブアプリに対してとある攻撃があったからです。

ネイティブアプリはCustom URL Schemeという仕組みがあります。これは例えばiPhoneで「caddi://hoge」というURLを指定すれば、インストールされたキャディのネイティブアプリを開くことができる仕組みです。

悪意ある人が別のアプリで「caddi:hoge」という全く同じCustom URL Schemeで競合させたアプリを作ります。

これをユーザーがインストールすると、認可リクエストのredirect_uri=caddi:hogeとなり、後からインストールされた悪いアプリ側の画面が開いてしまいます。

悪いアプリがcodeを受け取り、/oauth/tokenにリクエストしてアクセストークンを取得できてしまうわけです。

これを解消・対策するために出てきたものがPKCEで、code_verifierという任意の文字列を生成しておき認可リクエストを行うと、悪意のあるアプリに戻ってきた時に、code_verifierの情報がわからないので、アクセストークンをもらうことができないことで防ぐものです。

この攻撃以外にもPKCEは有効で、Single Page Applicationやネイティブアプリケーションは必ずPKCEを使うべきです。冒頭で少し紹介したFAPIでは、PKCEは必須であると定義されています。

地図情報システム入門

続いて、2021年1月25日に開催された社内勉強会、岩瀬からのプレゼン内容をまとめております。

https://speakerdeck.com/caddi_eng/20220125-iwase-di-li-qing-bao-sisutemuru-men-dot-pptx

緯度経度だけでは一意に場所は定まらない

岩瀬:

今回は、地理情報システム(GIS)に全く触れたことがない人向けの内容になっています。

内容としては、GISを扱うときに出てきそうな概念やツールなどを簡単に紹介していきます。

はじめに、次の数字をご覧ください。

こちらの数字は何を示しているでしょうか?

正解はキャディの住所になります。Google Mapからとってきた緯度経度の情報ですね。

さて、この情報を友人に教えたとして、この数字でキャディの会社の位置を特定できるはずです。

ところが実際に、別のサイトでやってみると・・なんと違う場所にヒットしまうのです。

これはなぜなのでしょうか?

実はこれ、測地系というものがあるのですが、緯度経度だけでは一意に場所は定まらないのです。

地球は完全な球体ではなく、厳密には楕円体なので、地球上の位置を緯度経度で表そうとすると、日本測地系と世界測地系では位置がズレてしまいます。

日本測地系は、昔から日本で使われてきたもので現在も一部で利用されていますが、GPSなどで使われているものは世界測地系といわれ、現在はほとんどこちらが使われています。

一意に場所を定めるために

岩瀬:

測地系と座標系を合わせて、空間参照系と言うものがあります。

コード体系としてはEPSGとよばれる空間参照系の識別コードがあるので、緯度経度の数値を扱うときは覚えておいてください。

座標系は、地理座標系とGoogle Map に利用されているWebメルカトルがありますが、これら座標系と測地系を組み合わせることで、一意に場所を定めることができるようになります。

位置情報のデータ形式

岩瀬:

さて、そうした位置情報の元になるデータ形式には、どのようなものがあるのでしょうか。

今回は、WKT(Well-Kown-Text)とShapefileの2つがあるので、ご紹介していきます。

まずWKTですが、こちらはベクタ形式の幾何学オブジェクトを投影法をもとに変換して、地図上に表現させるマークアップ言語です。

POINT、LINESTRING、POLYGONの3つが主流です。POLYGONは、最初と最後の数字は一致させる必要がある制約があるので注意が必要です。

これらはデータをテキストで保存する場合に利用され、対応ツールとしては、PostgreSQL、MySQL、BigQueryなどがあります。

続いてShapefileですが、こちらはEsri社が提唱したベクター形式のデータフォーマットです。

国土交通省が提供するデータでも使っていたりと、実質的には業界標準のフォーマットになっていて多くのGISツールが対応しています。

私はQGISという無料のソフトしか使用経験がありませんが、簡単に描画などするときには適していると思っています。

無料ながら高機能で、WindowsやMac OS、Linuxで利用可能です。

地理情報データを解析するとき

岩瀬:

続いて、地図上のとある区域でデータ集計することなどがあると思います。

たとえば都道府県ごとの状況を日本地図で表示することは、生活のあらゆるところで利用されていて、私たちもなじみ深いですよね。

ただ、統計情報で利用するときは、大きさがバラバラなので、単一面積など数値的に同じ条件で可視化したい場合には向いていません。

また、基本的には陸地のみで表示されるため、降水量の表示など海上部分を表現することも難しいです。

これを解決するために、地域メッシュという、緯度経度に基づいてほぼ同じ大きさの四角形で分割した領域を使うことがあります。

それぞれのメッシュには地域メッシュコードが付与されています。

1次メッシュがあり、それを8等分したものが2次メッシュ、さらに分割して3次・4次…と細かくあります。

降水量などは、こうした地域メッシュを用いて表現をしています。

また、地図上を六角形で分割したGeoHexというものもあります。

こちらはGoogle Mapと同じズームレベルで分けられていて、日本人が仕様検討したそうで純国産のものなのですが、統計情報よりも一部のゲームで利用されいる印象が強いです。

Web地図描画

岩瀬:

それからWeb地図に描画するとき、ライブラリとしてはLeafletなどを用います。

配信データ形式としては、ラスターデータは画像データなのでデータサイズが小さいため、路線図などで利用されています。

ベクターデータは、描画するときにオブジェクトに属性を持たせることができるのですが、数が増えてくるとデータサイズば大きくなってきてしまいます。

ラスタータイル地図は、Web地図では背景として使用されます。

また、XYZ方式はタイル状に分割された地図データ配信をするときによく利用されますので、タイル座標確認ページで使ってみてください。

GeoJsonは、JSON形式で空間データを表すフォーマットなのですが、テキスト形式なので人が読み書きしやすいメリットがあります。

MVT(Mapbox Vector Tile)は、Mapbox社が手動でやっているベクトルタイルの地図になっています。

テキスト形式では場合によってはエンコードが遅いので、それを解決するためにバイナリーデータで配信がされていて、通信データ量の削減ができるメリットがある一方で、デバッグが大変というデメリットもあります。

拡張子はmvtが推奨されているのですが、pdfになっているものも見かけたことがあります。

最後になりますが、Vue.js + Leafletを使用した簡単なサンプルをご紹介していきます。

これは、l-mapタグでマップの下地を作成し、その上に地理院地図のタイルレイヤーとキャディ関東物流拠点の場所をマーカーで描画したものになります。

タイル地図などを使用する場合ライセンス表記が必要になりますが、 attribute 属性に指定することで右下に描画する機能もあったりします。

ということで今回は、

・緯度経度だけでは場所は一位に決まらないので測地系などを考慮する必要がある ・データ形式もさまざまあるので、目的に応じて使い分けてみてください

というお話をさせていただきました。

おわりに

今回は、2回分の社内勉強会の内容をまとめてみたのですが、いかがでしたでしょうか。

記事内容をご覧いただいて、興味持った方はこちらにて、お話する機会をご用意しておりますので、ぜひご活用ください。

また社外向けに一般公開するイベントに関する情報は、キャディのCONNPASSをご用意しておりますので、こちらもご登録いただけますと幸いです。

最後までお読みいただきまして、ありがとうございます。