こんにちは。開発本部のエンジニアの鶴です。 今回は先月に行った社内の勉強会 TechLunch の内容をご紹介させていただきます。 イントロ Web サービスでは、ユーザーにアカウントを作ってもらい、ログインをしてサービスを利用してもらう、というユーザー認証を利用するサービスも多いかと思います。 Web サービスを開発する側としては、サービスごとに都度ユーザー認証の仕組みを構築する必要がありますが、セキュリティ対策の観点から考慮することが多く、地味に開発の工数がかかってしまいます。 また最近では、 Amazon Cognito や Firebase Authentication 、 Auth0 など、ユーザー認証サービスがいくつかリリースされ、ユーザー認証の機能をこれらの外部サービスに任せて開発の手間を省くという選択肢も取れるようになってきています。 自分自身、かつて担当したプロジェクトでユーザー認証の仕組みを 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 の組み合わせ。 これらのフローの違いは以下の表のとおりです。 ( 公式より引用 ) 今回は、 公式 や こちらの解説記事 などを参照しながら、基本の処理フローである AuthorizationCodeFlow について解説します。 簡略化のため、イメージ重視で登場人物は「 ユーザー 」「(ユーザーにサービスを提供する) Web サービス 」「 認証サービス 」と表現することにします。 大まかには以下のステップで処理が行われます。 ユーザー からのアクセスに対し、 Web サービス は 認証サービス にユーザー認証を要求する 認証サービス はユーザー認証を行い、認証コードを発行して、 ユーザー を Web サービス にリダイレクトさせる Web サービス は 2 で取得した認証コードを用いて 認証サービス に ID トークン等をリクエストする Web サービス は 3 で取得した ID トークンを検証し、 ユーザー の識別子を取得する Step.0 : 事前準備 あらかじめ Web サービス は 認証サービス からクライアント ID とクライアントシークレットを取得し保持しておきます。 Step.1: ユーザー認証の要求 ユーザー が Web サービス に対し一般的なログインの流れでログインを要求すると、 Web サービス は 認証サービス にリクエストをリダイレクトします。 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 で指定できるユーザー属性情報は以下のとおりです。 ( 公式より引用 ) ユーザーの認証でよく使われそうな「氏名」や「メールアドレス」など基本的な属性情報が定義されています。 state は CSRF 対策などのためのランダム値です。認証フローを開始するたびに Web サービス が発行し、リクエストとコールバックの間で値が維持されます。 他にもいくつかのパラメータ(nonce など)が定義されており、必要に応じて利用します。 Step.2: ユーザー認証と認証コードの発行 認証サービス では認証手段に応じてログイン ID ・パスワードの入力フォームなどを表示し、 ユーザー から認証情報を取得して認証処理を行います。 認証サービス はユーザーの認証に成功すると、認証コードを発行し、 ユーザー を 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 トークンなど)を取得します。 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 で表現されており、*認証サービス_の公開鍵を用いて検証することができます。 手順は こちら をご確認ください。他にも参考リンクを紹介しておきます。 https://qiita.com/bobunderson/items/d48f89e2b3e6ad9f9c4c https://qiita.com/TakahikoKawasaki/items/8f0e422c7edd2d220e06 下記は 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
こんにちは。開発本部のエンジニアの鶴です。 今回は先月に行った社内の勉強会 TechLunch の内容をご紹介させていただきます。 イントロ Web サービスでは、ユーザーにアカウントを作ってもらい、ログインをしてサービスを利用してもらう、というユーザー認証を利用するサービスも多いかと思います。 Web サービスを開発する側としては、サービスごとに都度ユーザー認証の仕組みを構築する必要がありますが、セキュリティ対策の観点から考慮することが多く、地味に開発の工数がかかってしまいます。 また最近では、 Amazon Cognito や Firebase Authentication 、 Auth0 など、ユーザー認証サービスがいくつかリリースされ、ユーザー認証の機能をこれらの外部サービスに任せて開発の手間を省くという選択肢も取れるようになってきています。 自分自身、かつて担当したプロジェクトでユーザー認証の仕組みを 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 の組み合わせ。 これらのフローの違いは以下の表のとおりです。 ( 公式より引用 ) 今回は、 公式 や こちらの解説記事 などを参照しながら、基本の処理フローである AuthorizationCodeFlow について解説します。 簡略化のため、イメージ重視で登場人物は「 ユーザー 」「(ユーザーにサービスを提供する) Web サービス 」「 認証サービス 」と表現することにします。 大まかには以下のステップで処理が行われます。 ユーザー からのアクセスに対し、 Web サービス は 認証サービス にユーザー認証を要求する 認証サービス はユーザー認証を行い、認証コードを発行して、 ユーザー を Web サービス にリダイレクトさせる Web サービス は 2 で取得した認証コードを用いて 認証サービス に ID トークン等をリクエストする Web サービス は 3 で取得した ID トークンを検証し、 ユーザー の識別子を取得する Step.0 : 事前準備 あらかじめ Web サービス は 認証サービス からクライアント ID とクライアントシークレットを取得し保持しておきます。 Step.1: ユーザー認証の要求 ユーザー が Web サービス に対し一般的なログインの流れでログインを要求すると、 Web サービス は 認証サービス にリクエストをリダイレクトします。 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 で指定できるユーザー属性情報は以下のとおりです。 ( 公式より引用 ) ユーザーの認証でよく使われそうな「氏名」や「メールアドレス」など基本的な属性情報が定義されています。 state は CSRF 対策などのためのランダム値です。認証フローを開始するたびに Web サービス が発行し、リクエストとコールバックの間で値が維持されます。 他にもいくつかのパラメータ(nonce など)が定義されており、必要に応じて利用します。 Step.2: ユーザー認証と認証コードの発行 認証サービス では認証手段に応じてログイン ID ・パスワードの入力フォームなどを表示し、 ユーザー から認証情報を取得して認証処理を行います。 認証サービス はユーザーの認証に成功すると、認証コードを発行し、 ユーザー を 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 トークンなど)を取得します。 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 で表現されており、*認証サービス_の公開鍵を用いて検証することができます。 手順は こちら をご確認ください。他にも参考リンクを紹介しておきます。 https://qiita.com/bobunderson/items/d48f89e2b3e6ad9f9c4c https://qiita.com/TakahikoKawasaki/items/8f0e422c7edd2d220e06 下記は 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
こんにちは。開発本部のエンジニアの鶴です。 今回は先月に行った社内の勉強会 TechLunch の内容をご紹介させていただきます。 イントロ Web サービスでは、ユーザーにアカウントを作ってもらい、ログインをしてサービスを利用してもらう、というユーザー認証を利用するサービスも多いかと思います。 Web サービスを開発する側としては、サービスごとに都度ユーザー認証の仕組みを構築する必要がありますが、セキュリティ対策の観点から考慮することが多く、地味に開発の工数がかかってしまいます。 また最近では、 Amazon Cognito や Firebase Authentication 、 Auth0 など、ユーザー認証サービスがいくつかリリースされ、ユーザー認証の機能をこれらの外部サービスに任せて開発の手間を省くという選択肢も取れるようになってきています。 自分自身、かつて担当したプロジェクトでユーザー認証の仕組みを 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 の組み合わせ。 これらのフローの違いは以下の表のとおりです。 ( 公式より引用 ) 今回は、 公式 や こちらの解説記事 などを参照しながら、基本の処理フローである AuthorizationCodeFlow について解説します。 簡略化のため、イメージ重視で登場人物は「 ユーザー 」「(ユーザーにサービスを提供する) Web サービス 」「 認証サービス 」と表現することにします。 大まかには以下のステップで処理が行われます。 ユーザー からのアクセスに対し、 Web サービス は 認証サービス にユーザー認証を要求する 認証サービス はユーザー認証を行い、認証コードを発行して、 ユーザー を Web サービス にリダイレクトさせる Web サービス は 2 で取得した認証コードを用いて 認証サービス に ID トークン等をリクエストする Web サービス は 3 で取得した ID トークンを検証し、 ユーザー の識別子を取得する Step.0 : 事前準備 あらかじめ Web サービス は 認証サービス からクライアント ID とクライアントシークレットを取得し保持しておきます。 Step.1: ユーザー認証の要求 ユーザー が Web サービス に対し一般的なログインの流れでログインを要求すると、 Web サービス は 認証サービス にリクエストをリダイレクトします。 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 で指定できるユーザー属性情報は以下のとおりです。 ( 公式より引用 ) ユーザーの認証でよく使われそうな「氏名」や「メールアドレス」など基本的な属性情報が定義されています。 state は CSRF 対策などのためのランダム値です。認証フローを開始するたびに Web サービス が発行し、リクエストとコールバックの間で値が維持されます。 他にもいくつかのパラメータ(nonce など)が定義されており、必要に応じて利用します。 Step.2: ユーザー認証と認証コードの発行 認証サービス では認証手段に応じてログイン ID ・パスワードの入力フォームなどを表示し、 ユーザー から認証情報を取得して認証処理を行います。 認証サービス はユーザーの認証に成功すると、認証コードを発行し、 ユーザー を 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 トークンなど)を取得します。 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 で表現されており、*認証サービス_の公開鍵を用いて検証することができます。 手順は こちら をご確認ください。他にも参考リンクを紹介しておきます。 https://qiita.com/bobunderson/items/d48f89e2b3e6ad9f9c4c https://qiita.com/TakahikoKawasaki/items/8f0e422c7edd2d220e06 下記は 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
こんにちは。開発本部のエンジニアの鶴です。 今回は先月に行った社内の勉強会 TechLunch の内容をご紹介させていただきます。 イントロ Web サービスでは、ユーザーにアカウントを作ってもらい、ログインをしてサービスを利用してもらう、というユーザー認証を利用するサービスも多いかと思います。 Web サービスを開発する側としては、サービスごとに都度ユーザー認証の仕組みを構築する必要がありますが、セキュリティ対策の観点から考慮することが多く、地味に開発の工数がかかってしまいます。 また最近では、 Amazon Cognito や Firebase Authentication 、 Auth0 など、ユーザー認証サービスがいくつかリリースされ、ユーザー認証の機能をこれらの外部サービスに任せて開発の手間を省くという選択肢も取れるようになってきています。 自分自身、かつて担当したプロジェクトでユーザー認証の仕組みを 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 の組み合わせ。 これらのフローの違いは以下の表のとおりです。 ( 公式より引用 ) 今回は、 公式 や こちらの解説記事 などを参照しながら、基本の処理フローである AuthorizationCodeFlow について解説します。 簡略化のため、イメージ重視で登場人物は「 ユーザー 」「(ユーザーにサービスを提供する) Web サービス 」「 認証サービス 」と表現することにします。 大まかには以下のステップで処理が行われます。 ユーザー からのアクセスに対し、 Web サービス は 認証サービス にユーザー認証を要求する 認証サービス はユーザー認証を行い、認証コードを発行して、 ユーザー を Web サービス にリダイレクトさせる Web サービス は 2 で取得した認証コードを用いて 認証サービス に ID トークン等をリクエストする Web サービス は 3 で取得した ID トークンを検証し、 ユーザー の識別子を取得する Step.0 : 事前準備 あらかじめ Web サービス は 認証サービス からクライアント ID とクライアントシークレットを取得し保持しておきます。 Step.1: ユーザー認証の要求 ユーザー が Web サービス に対し一般的なログインの流れでログインを要求すると、 Web サービス は 認証サービス にリクエストをリダイレクトします。 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 で指定できるユーザー属性情報は以下のとおりです。 ( 公式より引用 ) ユーザーの認証でよく使われそうな「氏名」や「メールアドレス」など基本的な属性情報が定義されています。 state は CSRF 対策などのためのランダム値です。認証フローを開始するたびに Web サービス が発行し、リクエストとコールバックの間で値が維持されます。 他にもいくつかのパラメータ(nonce など)が定義されており、必要に応じて利用します。 Step.2: ユーザー認証と認証コードの発行 認証サービス では認証手段に応じてログイン ID ・パスワードの入力フォームなどを表示し、 ユーザー から認証情報を取得して認証処理を行います。 認証サービス はユーザーの認証に成功すると、認証コードを発行し、 ユーザー を 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 トークンなど)を取得します。 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 で表現されており、*認証サービス_の公開鍵を用いて検証することができます。 手順は こちら をご確認ください。他にも参考リンクを紹介しておきます。 https://qiita.com/bobunderson/items/d48f89e2b3e6ad9f9c4c https://qiita.com/TakahikoKawasaki/items/8f0e422c7edd2d220e06 下記は 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
こんにちは。開発本部のエンジニアの鶴です。 今回は先月に行った社内の勉強会 TechLunch の内容をご紹介させていただきます。 イントロ Web サービスでは、ユーザーにアカウントを作ってもらい、ログインをしてサービスを利用してもらう、というユーザー認証を利用するサービスも多いかと思います。 Web サービスを開発する側としては、サービスごとに都度ユーザー認証の仕組みを構築する必要がありますが、セキュリティ対策の観点から考慮することが多く、地味に開発の工数がかかってしまいます。 また最近では、 Amazon Cognito や Firebase Authentication 、 Auth0 など、ユーザー認証サービスがいくつかリリースされ、ユーザー認証の機能をこれらの外部サービスに任せて開発の手間を省くという選択肢も取れるようになってきています。 自分自身、かつて担当したプロジェクトでユーザー認証の仕組みを 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 の組み合わせ。 これらのフローの違いは以下の表のとおりです。 ( 公式より引用 ) 今回は、 公式 や こちらの解説記事 などを参照しながら、基本の処理フローである AuthorizationCodeFlow について解説します。 簡略化のため、イメージ重視で登場人物は「 ユーザー 」「(ユーザーにサービスを提供する) Web サービス 」「 認証サービス 」と表現することにします。 大まかには以下のステップで処理が行われます。 ユーザー からのアクセスに対し、 Web サービス は 認証サービス にユーザー認証を要求する 認証サービス はユーザー認証を行い、認証コードを発行して、 ユーザー を Web サービス にリダイレクトさせる Web サービス は 2 で取得した認証コードを用いて 認証サービス に ID トークン等をリクエストする Web サービス は 3 で取得した ID トークンを検証し、 ユーザー の識別子を取得する Step.0 : 事前準備 あらかじめ Web サービス は 認証サービス からクライアント ID とクライアントシークレットを取得し保持しておきます。 Step.1: ユーザー認証の要求 ユーザー が Web サービス に対し一般的なログインの流れでログインを要求すると、 Web サービス は 認証サービス にリクエストをリダイレクトします。 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 で指定できるユーザー属性情報は以下のとおりです。 ( 公式より引用 ) ユーザーの認証でよく使われそうな「氏名」や「メールアドレス」など基本的な属性情報が定義されています。 state は CSRF 対策などのためのランダム値です。認証フローを開始するたびに Web サービス が発行し、リクエストとコールバックの間で値が維持されます。 他にもいくつかのパラメータ(nonce など)が定義されており、必要に応じて利用します。 Step.2: ユーザー認証と認証コードの発行 認証サービス では認証手段に応じてログイン ID ・パスワードの入力フォームなどを表示し、 ユーザー から認証情報を取得して認証処理を行います。 認証サービス はユーザーの認証に成功すると、認証コードを発行し、 ユーザー を 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 トークンなど)を取得します。 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 で表現されており、*認証サービス_の公開鍵を用いて検証することができます。 手順は こちら をご確認ください。他にも参考リンクを紹介しておきます。 https://qiita.com/bobunderson/items/d48f89e2b3e6ad9f9c4c https://qiita.com/TakahikoKawasaki/items/8f0e422c7edd2d220e06 下記は 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
こんにちは。開発本部のエンジニア・新居です。 メドレーは 4/18〜4/20 に開催された RubyKaigi 2019 に Breakfast Sponsor(朝食スポンサー)として協賛させていただきました( 一昨年の Ruby Sponsor 、 昨年の Lightning Talks Sponsor に続き、3 年目の協賛です)。 rubykaigi.org 2017 年のレポート developer.medley.jp 2018 年のレポート developer.medley.jp 2019 年は福岡県の福岡国際会議場での開催でした。会場に向かう途中の博多駅ではさっそく RubyKaigi のポスターに迎えられ、RubyKaigi ムードが高まっておりました。 博多駅ではさっそく RubyKaigi のポスターがお出迎え ということで、今年の RubyKaigi の様子をレポートさせていただきます。 www.marinemesse.or.jp Breakfast Sponsor の様子 今回は Breakfast Sponsor としての協賛で、RubyKaigi2 日目と 3 日目の朝 8 時 30 分から 10 時までの時間帯で、RubyKaigi に参加されるみなさんに朝食をご提供させていただきました。 朝食会場は福岡国際会議場内の 1F にあるレストラン ラコンテ さん。朝食の内容はビュッフェ形式で、焼き魚やオムレツなどの定番おかずと、福岡名産の辛子明太子や辛子高菜をたらふく食べられる朝食でした。 入り口でみなさんをお出迎えするエンジニア稲本 おしゃれなテラス席 ビュッフェに並ぶおかず フルーツもたくさん 「辛子明太 & 辛子高菜」乗せごはん 福岡名産の辛子明太子と辛子高菜を白ごはんに添えてたらふくいただきました 会場の様子、大盛況でした テラス席はグローバルな感じ Twitter でも朝食の様子を話題にしていただけたりと、ご満足いただけた様子が伺えました。 MEDLEY さんの朝食サービス、めっちゃメニューある。外で優雅に食べてます — Tsukasa OISHI (@tsukasa_oishi) April 18, 2019 MEDLEY さん提供の朝食はブュッフェ形式。洋風にしてみたけど、他にご飯や味噌汁もある。 #rubykaigi pic.twitter.com/W4eggL6PQt — thinca (@thinca) April 19, 2019 RubyKaigi と MEDLEY さんのおかげで健康的な生活してる…。 #rubykaigi pic.twitter.com/Z502pk3yKg — yebis0942 (@yebis0942) April 19, 2019 朝食で食べた明太子・高菜ご飯がおいしかった! MEDLEY さん、ありがとうございます! #rubykaigi — snagasawa (@snagasawa_) April 20, 2019 ご来場いただいた人数は、RubyKaigi2 日目(朝食 1 日目)は 379 名、3 日目(朝食 2 日目)は 411 名でした。 朝食会場の出入り口でご案内していると「美味しかったです、ありがとうございました!」というお声を直接いただけたりと、みなさんにご満足いただけたようで良かったです。 Breakfast Sponsor での参加は初めてでしたが、みなさんが満足気に朝食会場を後にする姿を見ているとこちらも嬉しい気持ちになりました。 朝食をご利用いただいたみなさん、本当にありがとうございました。 今年は Breakfast Sponsor という形でしたが、Ruby と Ruby コミュニティの発展のため、今後も様々な形で貢献していければと思います。 RubyKaigi 2019 の様子 今年も毎年恒例の Matz さんの Keynote から始まりました。 今年は「The Year of Concurrency」というテーマで、Ruby 3 についての発表でした。 Ruby 3 の Static Analysis、Performance、Concurrency あたりの話を中心に、Ruby の今後の展望について語られました。普段 Ruby を使って仕事をしている身として、Matz さんから Ruby 3 の話を聞けたのは貴重な時間でしたし、改めて Ruby の進化を実感できるセッションでした。 Matz さんの Keynote その他のセッションスケジュールについてはこちら。 rubykaigi.org 2 階にはブースゾーンがあり、セッションの合間にはたくさんの参加者で溢れかえっていました。 ブースゾーンは大盛況 ブースゾーンの出入り口付近には各社のノベルティ Ruby 関連書籍の展示も 会場 5 階(最上階)にはハックスペースが用意されていました。 ここで各々休憩したり、黙々と作業したり、仲間と談笑したりと、様々な用途に使われていました。 ハックスペース入り口 ハックスペースの中(このときはセッション中だったので空いてました) 福岡開催ならではの屋台スペースも用意されていました。 ランチタイムには屋台ラーメンなどが振る舞われ、めちゃくちゃ混み合っていましたが、こういう地域特有の催しは RubyKaigi を盛り上げてくれるので良いですね。 ランチ前になるとゾロゾロと人集りが ランチタイムの屋台は大行列 屋台でラーメンを食らう参加者を羨むエンジニア中畑 メドレーブースの様子 また、2 階のブースゾーンにはメドレーのブースも出展しました。 今回参加したメンバー全員で ノベルティーにはメドレーロゴ付きのうちわ、ステッカー、お水、そして恒例の絆創膏を用意しました。 RubyKaigi 2018 でもらったメドレーの絆創膏が、子供が怪我したときに役に立ったよ〜という嬉しいお声をいただいたりもしました。 靴擦れや擦り傷を負ったとき、お子さんが転んだときとかに役に立つので、今度見かけた際はぜひお持ち帰りください。 メドレーの絆創膏 ブースではメドレーの会社説明やメドレーが提供するサービスの説明などを行いました。 スポンサーとして初参加だった RubyKaigi 2017 に参加したときよりもメドレーのことを知っている人が増えているなあと実感しました。 ブースで対応するエンジニア達(中畑、稲本、橋本) Matz さんにも来ていただきました! 福岡の様子 そして福岡といえば美味しいごはんですよね。 1 日目の夜は RubyKaigi 2019 Official Party が開催され、中洲川端商店街を半貸切にして日本酒やうどん、ラーメンや地鶏などが振る舞われました。 RubyKaigi 2019 Official Party の会場・中洲川端商店街の Guide Map 大樽に入って日本酒が配られてました 日本酒のラインナップ  うどんを前に満面の笑みの広報・深澤 夜は福岡の美食を求めて街に繰り出しました。 絶品イカの活造り 定番モツ鍋 出汁が最高の水炊き 会場近くの某有名ラーメン店のきくらげラーメン あまりのうまさに昇天するエンジニア中畑 また、RubyKaigi 初参加の 2017 年から続けている神社参拝にも行ってきました。 今回は警固神社(けごじんじゃ)に参拝してきました。 kegojinja.or.jp 警固神社入り口 参拝するエンジニア中畑 さいごに 2017 年から 3 度目となる RubyKaigi の協賛の様子をお届けしました。 Breakfast Sponsor として、RubyKaigi 参加者のみなさんにご満足いただけて本当に良かったなあと思います。 繰り返しになりますが、Ruby と Ruby コミュニティの発展のため、今後も様々な形で貢献していければと思います。 来年 2020 年は長野県松本市での開催ということで、またみなさんとお会いできることを願って、レポートを締めたいと思います。 rubykaigi.org お知らせ メドレーでは医療業界に存在する課題に IT を駆使して取り組んでいきたいメンバーを、デザイナー・エンジニアを中心に全職種絶賛募集中です。皆さまからのご応募お待ちしております。 www.medley.jp
こんにちは。開発本部のエンジニア・新居です。 メドレーは 4/18〜4/20 に開催された RubyKaigi 2019 に Breakfast Sponsor(朝食スポンサー)として協賛させていただきました( 一昨年の Ruby Sponsor 、 昨年の Lightning Talks Sponsor に続き、3 年目の協賛です)。 rubykaigi.org 2017 年のレポート developer.medley.jp 2018 年のレポート developer.medley.jp 2019 年は福岡県の福岡国際会議場での開催でした。会場に向かう途中の博多駅ではさっそく RubyKaigi のポスターに迎えられ、RubyKaigi ムードが高まっておりました。 博多駅ではさっそく RubyKaigi のポスターがお出迎え ということで、今年の RubyKaigi の様子をレポートさせていただきます。 www.marinemesse.or.jp Breakfast Sponsor の様子 今回は Breakfast Sponsor としての協賛で、RubyKaigi2 日目と 3 日目の朝 8 時 30 分から 10 時までの時間帯で、RubyKaigi に参加されるみなさんに朝食をご提供させていただきました。 朝食会場は福岡国際会議場内の 1F にあるレストラン ラコンテ さん。朝食の内容はビュッフェ形式で、焼き魚やオムレツなどの定番おかずと、福岡名産の辛子明太子や辛子高菜をたらふく食べられる朝食でした。 入り口でみなさんをお出迎えするエンジニア稲本 おしゃれなテラス席 ビュッフェに並ぶおかず フルーツもたくさん 「辛子明太 & 辛子高菜」乗せごはん 福岡名産の辛子明太子と辛子高菜を白ごはんに添えてたらふくいただきました 会場の様子、大盛況でした テラス席はグローバルな感じ Twitter でも朝食の様子を話題にしていただけたりと、ご満足いただけた様子が伺えました。 MEDLEY さんの朝食サービス、めっちゃメニューある。外で優雅に食べてます — Tsukasa OISHI (@tsukasa_oishi) April 18, 2019 MEDLEY さん提供の朝食はブュッフェ形式。洋風にしてみたけど、他にご飯や味噌汁もある。 #rubykaigi pic.twitter.com/W4eggL6PQt — thinca (@thinca) April 19, 2019 RubyKaigi と MEDLEY さんのおかげで健康的な生活してる…。 #rubykaigi pic.twitter.com/Z502pk3yKg — yebis0942 (@yebis0942) April 19, 2019 朝食で食べた明太子・高菜ご飯がおいしかった! MEDLEY さん、ありがとうございます! #rubykaigi — snagasawa (@snagasawa_) April 20, 2019 ご来場いただいた人数は、RubyKaigi2 日目(朝食 1 日目)は 379 名、3 日目(朝食 2 日目)は 411 名でした。 朝食会場の出入り口でご案内していると「美味しかったです、ありがとうございました!」というお声を直接いただけたりと、みなさんにご満足いただけたようで良かったです。 Breakfast Sponsor での参加は初めてでしたが、みなさんが満足気に朝食会場を後にする姿を見ているとこちらも嬉しい気持ちになりました。 朝食をご利用いただいたみなさん、本当にありがとうございました。 今年は Breakfast Sponsor という形でしたが、Ruby と Ruby コミュニティの発展のため、今後も様々な形で貢献していければと思います。 RubyKaigi 2019 の様子 今年も毎年恒例の Matz さんの Keynote から始まりました。 今年は「The Year of Concurrency」というテーマで、Ruby 3 についての発表でした。 Ruby 3 の Static Analysis、Performance、Concurrency あたりの話を中心に、Ruby の今後の展望について語られました。普段 Ruby を使って仕事をしている身として、Matz さんから Ruby 3 の話を聞けたのは貴重な時間でしたし、改めて Ruby の進化を実感できるセッションでした。 Matz さんの Keynote その他のセッションスケジュールについてはこちら。 rubykaigi.org 2 階にはブースゾーンがあり、セッションの合間にはたくさんの参加者で溢れかえっていました。 ブースゾーンは大盛況 ブースゾーンの出入り口付近には各社のノベルティ Ruby 関連書籍の展示も 会場 5 階(最上階)にはハックスペースが用意されていました。 ここで各々休憩したり、黙々と作業したり、仲間と談笑したりと、様々な用途に使われていました。 ハックスペース入り口 ハックスペースの中(このときはセッション中だったので空いてました) 福岡開催ならではの屋台スペースも用意されていました。 ランチタイムには屋台ラーメンなどが振る舞われ、めちゃくちゃ混み合っていましたが、こういう地域特有の催しは RubyKaigi を盛り上げてくれるので良いですね。 ランチ前になるとゾロゾロと人集りが ランチタイムの屋台は大行列 屋台でラーメンを食らう参加者を羨むエンジニア中畑 メドレーブースの様子 また、2 階のブースゾーンにはメドレーのブースも出展しました。 今回参加したメンバー全員で ノベルティーにはメドレーロゴ付きのうちわ、ステッカー、お水、そして恒例の絆創膏を用意しました。 RubyKaigi 2018 でもらったメドレーの絆創膏が、子供が怪我したときに役に立ったよ〜という嬉しいお声をいただいたりもしました。 靴擦れや擦り傷を負ったとき、お子さんが転んだときとかに役に立つので、今度見かけた際はぜひお持ち帰りください。 メドレーの絆創膏 ブースではメドレーの会社説明やメドレーが提供するサービスの説明などを行いました。 スポンサーとして初参加だった RubyKaigi 2017 に参加したときよりもメドレーのことを知っている人が増えているなあと実感しました。 ブースで対応するエンジニア達(中畑、稲本、橋本) Matz さんにも来ていただきました! 福岡の様子 そして福岡といえば美味しいごはんですよね。 1 日目の夜は RubyKaigi 2019 Official Party が開催され、中洲川端商店街を半貸切にして日本酒やうどん、ラーメンや地鶏などが振る舞われました。 RubyKaigi 2019 Official Party の会場・中洲川端商店街の Guide Map 大樽に入って日本酒が配られてました 日本酒のラインナップ  うどんを前に満面の笑みの広報・深澤 夜は福岡の美食を求めて街に繰り出しました。 絶品イカの活造り 定番モツ鍋 出汁が最高の水炊き 会場近くの某有名ラーメン店のきくらげラーメン あまりのうまさに昇天するエンジニア中畑 また、RubyKaigi 初参加の 2017 年から続けている神社参拝にも行ってきました。 今回は警固神社(けごじんじゃ)に参拝してきました。 kegojinja.or.jp 警固神社入り口 参拝するエンジニア中畑 さいごに 2017 年から 3 度目となる RubyKaigi の協賛の様子をお届けしました。 Breakfast Sponsor として、RubyKaigi 参加者のみなさんにご満足いただけて本当に良かったなあと思います。 繰り返しになりますが、Ruby と Ruby コミュニティの発展のため、今後も様々な形で貢献していければと思います。 来年 2020 年は長野県松本市での開催ということで、またみなさんとお会いできることを願って、レポートを締めたいと思います。 rubykaigi.org お知らせ メドレーでは医療業界に存在する課題に IT を駆使して取り組んでいきたいメンバーを、デザイナー・エンジニアを中心に全職種絶賛募集中です。皆さまからのご応募お待ちしております。 www.medley.jp
こんにちは。開発本部のエンジニア・新居です。 メドレーは 4/18〜4/20 に開催された RubyKaigi 2019 に Breakfast Sponsor(朝食スポンサー)として協賛させていただきました( 一昨年の Ruby Sponsor 、 昨年の Lightning Talks Sponsor に続き、3 年目の協賛です)。 rubykaigi.org 2017 年のレポート developer.medley.jp 2018 年のレポート developer.medley.jp 2019 年は福岡県の福岡国際会議場での開催でした。会場に向かう途中の博多駅ではさっそく RubyKaigi のポスターに迎えられ、RubyKaigi ムードが高まっておりました。 博多駅ではさっそく RubyKaigi のポスターがお出迎え ということで、今年の RubyKaigi の様子をレポートさせていただきます。 www.marinemesse.or.jp Breakfast Sponsor の様子 今回は Breakfast Sponsor としての協賛で、RubyKaigi2 日目と 3 日目の朝 8 時 30 分から 10 時までの時間帯で、RubyKaigi に参加されるみなさんに朝食をご提供させていただきました。 朝食会場は福岡国際会議場内の 1F にあるレストラン ラコンテ さん。朝食の内容はビュッフェ形式で、焼き魚やオムレツなどの定番おかずと、福岡名産の辛子明太子や辛子高菜をたらふく食べられる朝食でした。 入り口でみなさんをお出迎えするエンジニア稲本 おしゃれなテラス席 ビュッフェに並ぶおかず フルーツもたくさん 「辛子明太 & 辛子高菜」乗せごはん 福岡名産の辛子明太子と辛子高菜を白ごはんに添えてたらふくいただきました 会場の様子、大盛況でした テラス席はグローバルな感じ Twitter でも朝食の様子を話題にしていただけたりと、ご満足いただけた様子が伺えました。 MEDLEY さんの朝食サービス、めっちゃメニューある。外で優雅に食べてます — Tsukasa OISHI (@tsukasa_oishi) April 18, 2019 MEDLEY さん提供の朝食はブュッフェ形式。洋風にしてみたけど、他にご飯や味噌汁もある。 #rubykaigi pic.twitter.com/W4eggL6PQt — thinca (@thinca) April 19, 2019 RubyKaigi と MEDLEY さんのおかげで健康的な生活してる…。 #rubykaigi pic.twitter.com/Z502pk3yKg — yebis0942 (@yebis0942) April 19, 2019 朝食で食べた明太子・高菜ご飯がおいしかった! MEDLEY さん、ありがとうございます! #rubykaigi — snagasawa (@snagasawa_) April 20, 2019 ご来場いただいた人数は、RubyKaigi2 日目(朝食 1 日目)は 379 名、3 日目(朝食 2 日目)は 411 名でした。 朝食会場の出入り口でご案内していると「美味しかったです、ありがとうございました!」というお声を直接いただけたりと、みなさんにご満足いただけたようで良かったです。 Breakfast Sponsor での参加は初めてでしたが、みなさんが満足気に朝食会場を後にする姿を見ているとこちらも嬉しい気持ちになりました。 朝食をご利用いただいたみなさん、本当にありがとうございました。 今年は Breakfast Sponsor という形でしたが、Ruby と Ruby コミュニティの発展のため、今後も様々な形で貢献していければと思います。 RubyKaigi 2019 の様子 今年も毎年恒例の Matz さんの Keynote から始まりました。 今年は「The Year of Concurrency」というテーマで、Ruby 3 についての発表でした。 Ruby 3 の Static Analysis、Performance、Concurrency あたりの話を中心に、Ruby の今後の展望について語られました。普段 Ruby を使って仕事をしている身として、Matz さんから Ruby 3 の話を聞けたのは貴重な時間でしたし、改めて Ruby の進化を実感できるセッションでした。 Matz さんの Keynote その他のセッションスケジュールについてはこちら。 rubykaigi.org 2 階にはブースゾーンがあり、セッションの合間にはたくさんの参加者で溢れかえっていました。 ブースゾーンは大盛況 ブースゾーンの出入り口付近には各社のノベルティ Ruby 関連書籍の展示も 会場 5 階(最上階)にはハックスペースが用意されていました。 ここで各々休憩したり、黙々と作業したり、仲間と談笑したりと、様々な用途に使われていました。 ハックスペース入り口 ハックスペースの中(このときはセッション中だったので空いてました) 福岡開催ならではの屋台スペースも用意されていました。 ランチタイムには屋台ラーメンなどが振る舞われ、めちゃくちゃ混み合っていましたが、こういう地域特有の催しは RubyKaigi を盛り上げてくれるので良いですね。 ランチ前になるとゾロゾロと人集りが ランチタイムの屋台は大行列 屋台でラーメンを食らう参加者を羨むエンジニア中畑 メドレーブースの様子 また、2 階のブースゾーンにはメドレーのブースも出展しました。 今回参加したメンバー全員で ノベルティーにはメドレーロゴ付きのうちわ、ステッカー、お水、そして恒例の絆創膏を用意しました。 RubyKaigi 2018 でもらったメドレーの絆創膏が、子供が怪我したときに役に立ったよ〜という嬉しいお声をいただいたりもしました。 靴擦れや擦り傷を負ったとき、お子さんが転んだときとかに役に立つので、今度見かけた際はぜひお持ち帰りください。 メドレーの絆創膏 ブースではメドレーの会社説明やメドレーが提供するサービスの説明などを行いました。 スポンサーとして初参加だった RubyKaigi 2017 に参加したときよりもメドレーのことを知っている人が増えているなあと実感しました。 ブースで対応するエンジニア達(中畑、稲本、橋本) Matz さんにも来ていただきました! 福岡の様子 そして福岡といえば美味しいごはんですよね。 1 日目の夜は RubyKaigi 2019 Official Party が開催され、中洲川端商店街を半貸切にして日本酒やうどん、ラーメンや地鶏などが振る舞われました。 RubyKaigi 2019 Official Party の会場・中洲川端商店街の Guide Map 大樽に入って日本酒が配られてました 日本酒のラインナップ  うどんを前に満面の笑みの広報・深澤 夜は福岡の美食を求めて街に繰り出しました。 絶品イカの活造り 定番モツ鍋 出汁が最高の水炊き 会場近くの某有名ラーメン店のきくらげラーメン あまりのうまさに昇天するエンジニア中畑 また、RubyKaigi 初参加の 2017 年から続けている神社参拝にも行ってきました。 今回は警固神社(けごじんじゃ)に参拝してきました。 kegojinja.or.jp 警固神社入り口 参拝するエンジニア中畑 さいごに 2017 年から 3 度目となる RubyKaigi の協賛の様子をお届けしました。 Breakfast Sponsor として、RubyKaigi 参加者のみなさんにご満足いただけて本当に良かったなあと思います。 繰り返しになりますが、Ruby と Ruby コミュニティの発展のため、今後も様々な形で貢献していければと思います。 来年 2020 年は長野県松本市での開催ということで、またみなさんとお会いできることを願って、レポートを締めたいと思います。 rubykaigi.org お知らせ メドレーでは医療業界に存在する課題に IT を駆使して取り組んでいきたいメンバーを、デザイナー・エンジニアを中心に全職種絶賛募集中です。皆さまからのご応募お待ちしております。 www.medley.jp
こんにちは。開発本部のエンジニア・新居です。 メドレーは 4/18〜4/20 に開催された RubyKaigi 2019 に Breakfast Sponsor(朝食スポンサー)として協賛させていただきました( 一昨年の Ruby Sponsor 、 昨年の Lightning Talks Sponsor に続き、3 年目の協賛です)。 rubykaigi.org 2017 年のレポート developer.medley.jp 2018 年のレポート developer.medley.jp 2019 年は福岡県の福岡国際会議場での開催でした。会場に向かう途中の博多駅ではさっそく RubyKaigi のポスターに迎えられ、RubyKaigi ムードが高まっておりました。 博多駅ではさっそく RubyKaigi のポスターがお出迎え ということで、今年の RubyKaigi の様子をレポートさせていただきます。 www.marinemesse.or.jp Breakfast Sponsor の様子 今回は Breakfast Sponsor としての協賛で、RubyKaigi2 日目と 3 日目の朝 8 時 30 分から 10 時までの時間帯で、RubyKaigi に参加されるみなさんに朝食をご提供させていただきました。 朝食会場は福岡国際会議場内の 1F にあるレストラン ラコンテ さん。朝食の内容はビュッフェ形式で、焼き魚やオムレツなどの定番おかずと、福岡名産の辛子明太子や辛子高菜をたらふく食べられる朝食でした。 入り口でみなさんをお出迎えするエンジニア稲本 おしゃれなテラス席 ビュッフェに並ぶおかず フルーツもたくさん 「辛子明太 & 辛子高菜」乗せごはん 福岡名産の辛子明太子と辛子高菜を白ごはんに添えてたらふくいただきました 会場の様子、大盛況でした テラス席はグローバルな感じ Twitter でも朝食の様子を話題にしていただけたりと、ご満足いただけた様子が伺えました。 MEDLEY さんの朝食サービス、めっちゃメニューある。外で優雅に食べてます — Tsukasa OISHI (@tsukasa_oishi) April 18, 2019 MEDLEY さん提供の朝食はブュッフェ形式。洋風にしてみたけど、他にご飯や味噌汁もある。 #rubykaigi pic.twitter.com/W4eggL6PQt — thinca (@thinca) April 19, 2019 RubyKaigi と MEDLEY さんのおかげで健康的な生活してる…。 #rubykaigi pic.twitter.com/Z502pk3yKg — yebis0942 (@yebis0942) April 19, 2019 朝食で食べた明太子・高菜ご飯がおいしかった! MEDLEY さん、ありがとうございます! #rubykaigi — snagasawa (@snagasawa_) April 20, 2019 ご来場いただいた人数は、RubyKaigi2 日目(朝食 1 日目)は 379 名、3 日目(朝食 2 日目)は 411 名でした。 朝食会場の出入り口でご案内していると「美味しかったです、ありがとうございました!」というお声を直接いただけたりと、みなさんにご満足いただけたようで良かったです。 Breakfast Sponsor での参加は初めてでしたが、みなさんが満足気に朝食会場を後にする姿を見ているとこちらも嬉しい気持ちになりました。 朝食をご利用いただいたみなさん、本当にありがとうございました。 今年は Breakfast Sponsor という形でしたが、Ruby と Ruby コミュニティの発展のため、今後も様々な形で貢献していければと思います。 RubyKaigi 2019 の様子 今年も毎年恒例の Matz さんの Keynote から始まりました。 今年は「The Year of Concurrency」というテーマで、Ruby 3 についての発表でした。 Ruby 3 の Static Analysis、Performance、Concurrency あたりの話を中心に、Ruby の今後の展望について語られました。普段 Ruby を使って仕事をしている身として、Matz さんから Ruby 3 の話を聞けたのは貴重な時間でしたし、改めて Ruby の進化を実感できるセッションでした。 Matz さんの Keynote その他のセッションスケジュールについてはこちら。 rubykaigi.org 2 階にはブースゾーンがあり、セッションの合間にはたくさんの参加者で溢れかえっていました。 ブースゾーンは大盛況 ブースゾーンの出入り口付近には各社のノベルティ Ruby 関連書籍の展示も 会場 5 階(最上階)にはハックスペースが用意されていました。 ここで各々休憩したり、黙々と作業したり、仲間と談笑したりと、様々な用途に使われていました。 ハックスペース入り口 ハックスペースの中(このときはセッション中だったので空いてました) 福岡開催ならではの屋台スペースも用意されていました。 ランチタイムには屋台ラーメンなどが振る舞われ、めちゃくちゃ混み合っていましたが、こういう地域特有の催しは RubyKaigi を盛り上げてくれるので良いですね。 ランチ前になるとゾロゾロと人集りが ランチタイムの屋台は大行列 屋台でラーメンを食らう参加者を羨むエンジニア中畑 メドレーブースの様子 また、2 階のブースゾーンにはメドレーのブースも出展しました。 今回参加したメンバー全員で ノベルティーにはメドレーロゴ付きのうちわ、ステッカー、お水、そして恒例の絆創膏を用意しました。 RubyKaigi 2018 でもらったメドレーの絆創膏が、子供が怪我したときに役に立ったよ〜という嬉しいお声をいただいたりもしました。 靴擦れや擦り傷を負ったとき、お子さんが転んだときとかに役に立つので、今度見かけた際はぜひお持ち帰りください。 メドレーの絆創膏 ブースではメドレーの会社説明やメドレーが提供するサービスの説明などを行いました。 スポンサーとして初参加だった RubyKaigi 2017 に参加したときよりもメドレーのことを知っている人が増えているなあと実感しました。 ブースで対応するエンジニア達(中畑、稲本、橋本) Matz さんにも来ていただきました! 福岡の様子 そして福岡といえば美味しいごはんですよね。 1 日目の夜は RubyKaigi 2019 Official Party が開催され、中洲川端商店街を半貸切にして日本酒やうどん、ラーメンや地鶏などが振る舞われました。 RubyKaigi 2019 Official Party の会場・中洲川端商店街の Guide Map 大樽に入って日本酒が配られてました 日本酒のラインナップ  うどんを前に満面の笑みの広報・深澤 夜は福岡の美食を求めて街に繰り出しました。 絶品イカの活造り 定番モツ鍋 出汁が最高の水炊き 会場近くの某有名ラーメン店のきくらげラーメン あまりのうまさに昇天するエンジニア中畑 また、RubyKaigi 初参加の 2017 年から続けている神社参拝にも行ってきました。 今回は警固神社(けごじんじゃ)に参拝してきました。 kegojinja.or.jp 警固神社入り口 参拝するエンジニア中畑 さいごに 2017 年から 3 度目となる RubyKaigi の協賛の様子をお届けしました。 Breakfast Sponsor として、RubyKaigi 参加者のみなさんにご満足いただけて本当に良かったなあと思います。 繰り返しになりますが、Ruby と Ruby コミュニティの発展のため、今後も様々な形で貢献していければと思います。 来年 2020 年は長野県松本市での開催ということで、またみなさんとお会いできることを願って、レポートを締めたいと思います。 rubykaigi.org お知らせ メドレーでは医療業界に存在する課題に IT を駆使して取り組んでいきたいメンバーを、デザイナー・エンジニアを中心に全職種絶賛募集中です。皆さまからのご応募お待ちしております。 www.medley.jp
こんにちは。開発本部のエンジニア・新居です。 メドレーは 4/18〜4/20 に開催された RubyKaigi 2019 に Breakfast Sponsor(朝食スポンサー)として協賛させていただきました( 一昨年の Ruby Sponsor 、 昨年の Lightning Talks Sponsor に続き、3 年目の協賛です)。 rubykaigi.org 2017 年のレポート developer.medley.jp 2018 年のレポート developer.medley.jp 2019 年は福岡県の福岡国際会議場での開催でした。会場に向かう途中の博多駅ではさっそく RubyKaigi のポスターに迎えられ、RubyKaigi ムードが高まっておりました。 博多駅ではさっそく RubyKaigi のポスターがお出迎え ということで、今年の RubyKaigi の様子をレポートさせていただきます。 www.marinemesse.or.jp Breakfast Sponsor の様子 今回は Breakfast Sponsor としての協賛で、RubyKaigi2 日目と 3 日目の朝 8 時 30 分から 10 時までの時間帯で、RubyKaigi に参加されるみなさんに朝食をご提供させていただきました。 朝食会場は福岡国際会議場内の 1F にあるレストラン ラコンテ さん。朝食の内容はビュッフェ形式で、焼き魚やオムレツなどの定番おかずと、福岡名産の辛子明太子や辛子高菜をたらふく食べられる朝食でした。 入り口でみなさんをお出迎えするエンジニア稲本 おしゃれなテラス席 ビュッフェに並ぶおかず フルーツもたくさん 「辛子明太 & 辛子高菜」乗せごはん 福岡名産の辛子明太子と辛子高菜を白ごはんに添えてたらふくいただきました 会場の様子、大盛況でした テラス席はグローバルな感じ Twitter でも朝食の様子を話題にしていただけたりと、ご満足いただけた様子が伺えました。 MEDLEY さんの朝食サービス、めっちゃメニューある。外で優雅に食べてます — Tsukasa OISHI (@tsukasa_oishi) April 18, 2019 MEDLEY さん提供の朝食はブュッフェ形式。洋風にしてみたけど、他にご飯や味噌汁もある。 #rubykaigi pic.twitter.com/W4eggL6PQt — thinca (@thinca) April 19, 2019 RubyKaigi と MEDLEY さんのおかげで健康的な生活してる…。 #rubykaigi pic.twitter.com/Z502pk3yKg — yebis0942 (@yebis0942) April 19, 2019 朝食で食べた明太子・高菜ご飯がおいしかった! MEDLEY さん、ありがとうございます! #rubykaigi — snagasawa (@snagasawa_) April 20, 2019 ご来場いただいた人数は、RubyKaigi2 日目(朝食 1 日目)は 379 名、3 日目(朝食 2 日目)は 411 名でした。 朝食会場の出入り口でご案内していると「美味しかったです、ありがとうございました!」というお声を直接いただけたりと、みなさんにご満足いただけたようで良かったです。 Breakfast Sponsor での参加は初めてでしたが、みなさんが満足気に朝食会場を後にする姿を見ているとこちらも嬉しい気持ちになりました。 朝食をご利用いただいたみなさん、本当にありがとうございました。 今年は Breakfast Sponsor という形でしたが、Ruby と Ruby コミュニティの発展のため、今後も様々な形で貢献していければと思います。 RubyKaigi 2019 の様子 今年も毎年恒例の Matz さんの Keynote から始まりました。 今年は「The Year of Concurrency」というテーマで、Ruby 3 についての発表でした。 Ruby 3 の Static Analysis、Performance、Concurrency あたりの話を中心に、Ruby の今後の展望について語られました。普段 Ruby を使って仕事をしている身として、Matz さんから Ruby 3 の話を聞けたのは貴重な時間でしたし、改めて Ruby の進化を実感できるセッションでした。 Matz さんの Keynote その他のセッションスケジュールについてはこちら。 rubykaigi.org 2 階にはブースゾーンがあり、セッションの合間にはたくさんの参加者で溢れかえっていました。 ブースゾーンは大盛況 ブースゾーンの出入り口付近には各社のノベルティ Ruby 関連書籍の展示も 会場 5 階(最上階)にはハックスペースが用意されていました。 ここで各々休憩したり、黙々と作業したり、仲間と談笑したりと、様々な用途に使われていました。 ハックスペース入り口 ハックスペースの中(このときはセッション中だったので空いてました) 福岡開催ならではの屋台スペースも用意されていました。 ランチタイムには屋台ラーメンなどが振る舞われ、めちゃくちゃ混み合っていましたが、こういう地域特有の催しは RubyKaigi を盛り上げてくれるので良いですね。 ランチ前になるとゾロゾロと人集りが ランチタイムの屋台は大行列 屋台でラーメンを食らう参加者を羨むエンジニア中畑 メドレーブースの様子 また、2 階のブースゾーンにはメドレーのブースも出展しました。 今回参加したメンバー全員で ノベルティーにはメドレーロゴ付きのうちわ、ステッカー、お水、そして恒例の絆創膏を用意しました。 RubyKaigi 2018 でもらったメドレーの絆創膏が、子供が怪我したときに役に立ったよ〜という嬉しいお声をいただいたりもしました。 靴擦れや擦り傷を負ったとき、お子さんが転んだときとかに役に立つので、今度見かけた際はぜひお持ち帰りください。 メドレーの絆創膏 ブースではメドレーの会社説明やメドレーが提供するサービスの説明などを行いました。 スポンサーとして初参加だった RubyKaigi 2017 に参加したときよりもメドレーのことを知っている人が増えているなあと実感しました。 ブースで対応するエンジニア達(中畑、稲本、橋本) Matz さんにも来ていただきました! 福岡の様子 そして福岡といえば美味しいごはんですよね。 1 日目の夜は RubyKaigi 2019 Official Party が開催され、中洲川端商店街を半貸切にして日本酒やうどん、ラーメンや地鶏などが振る舞われました。 RubyKaigi 2019 Official Party の会場・中洲川端商店街の Guide Map 大樽に入って日本酒が配られてました 日本酒のラインナップ  うどんを前に満面の笑みの広報・深澤 夜は福岡の美食を求めて街に繰り出しました。 絶品イカの活造り 定番モツ鍋 出汁が最高の水炊き 会場近くの某有名ラーメン店のきくらげラーメン あまりのうまさに昇天するエンジニア中畑 また、RubyKaigi 初参加の 2017 年から続けている神社参拝にも行ってきました。 今回は警固神社(けごじんじゃ)に参拝してきました。 kegojinja.or.jp 警固神社入り口 参拝するエンジニア中畑 さいごに 2017 年から 3 度目となる RubyKaigi の協賛の様子をお届けしました。 Breakfast Sponsor として、RubyKaigi 参加者のみなさんにご満足いただけて本当に良かったなあと思います。 繰り返しになりますが、Ruby と Ruby コミュニティの発展のため、今後も様々な形で貢献していければと思います。 来年 2020 年は長野県松本市での開催ということで、またみなさんとお会いできることを願って、レポートを締めたいと思います。 rubykaigi.org お知らせ メドレーでは医療業界に存在する課題に IT を駆使して取り組んでいきたいメンバーを、デザイナー・エンジニアを中心に全職種絶賛募集中です。皆さまからのご応募お待ちしております。 www.medley.jp
こんにちは。開発本部のエンジニア・新居です。 メドレーは 4/18〜4/20 に開催された RubyKaigi 2019 に Breakfast Sponsor(朝食スポンサー)として協賛させていただきました( 一昨年の Ruby Sponsor 、 昨年の Lightning Talks Sponsor に続き、3 年目の協賛です)。 rubykaigi.org 2017 年のレポート developer.medley.jp 2018 年のレポート developer.medley.jp 2019 年は福岡県の福岡国際会議場での開催でした。会場に向かう途中の博多駅ではさっそく RubyKaigi のポスターに迎えられ、RubyKaigi ムードが高まっておりました。 博多駅ではさっそく RubyKaigi のポスターがお出迎え ということで、今年の RubyKaigi の様子をレポートさせていただきます。 www.marinemesse.or.jp Breakfast Sponsor の様子 今回は Breakfast Sponsor としての協賛で、RubyKaigi2 日目と 3 日目の朝 8 時 30 分から 10 時までの時間帯で、RubyKaigi に参加されるみなさんに朝食をご提供させていただきました。 朝食会場は福岡国際会議場内の 1F にあるレストラン ラコンテ さん。朝食の内容はビュッフェ形式で、焼き魚やオムレツなどの定番おかずと、福岡名産の辛子明太子や辛子高菜をたらふく食べられる朝食でした。 入り口でみなさんをお出迎えするエンジニア稲本 おしゃれなテラス席 ビュッフェに並ぶおかず フルーツもたくさん 「辛子明太 & 辛子高菜」乗せごはん 福岡名産の辛子明太子と辛子高菜を白ごはんに添えてたらふくいただきました 会場の様子、大盛況でした テラス席はグローバルな感じ Twitter でも朝食の様子を話題にしていただけたりと、ご満足いただけた様子が伺えました。 MEDLEY さんの朝食サービス、めっちゃメニューある。外で優雅に食べてます — Tsukasa OISHI (@tsukasa_oishi) April 18, 2019 MEDLEY さん提供の朝食はブュッフェ形式。洋風にしてみたけど、他にご飯や味噌汁もある。 #rubykaigi pic.twitter.com/W4eggL6PQt — thinca (@thinca) April 19, 2019 RubyKaigi と MEDLEY さんのおかげで健康的な生活してる…。 #rubykaigi pic.twitter.com/Z502pk3yKg — yebis0942 (@yebis0942) April 19, 2019 朝食で食べた明太子・高菜ご飯がおいしかった! MEDLEY さん、ありがとうございます! #rubykaigi — snagasawa (@snagasawa_) April 20, 2019 ご来場いただいた人数は、RubyKaigi2 日目(朝食 1 日目)は 379 名、3 日目(朝食 2 日目)は 411 名でした。 朝食会場の出入り口でご案内していると「美味しかったです、ありがとうございました!」というお声を直接いただけたりと、みなさんにご満足いただけたようで良かったです。 Breakfast Sponsor での参加は初めてでしたが、みなさんが満足気に朝食会場を後にする姿を見ているとこちらも嬉しい気持ちになりました。 朝食をご利用いただいたみなさん、本当にありがとうございました。 今年は Breakfast Sponsor という形でしたが、Ruby と Ruby コミュニティの発展のため、今後も様々な形で貢献していければと思います。 RubyKaigi 2019 の様子 今年も毎年恒例の Matz さんの Keynote から始まりました。 今年は「The Year of Concurrency」というテーマで、Ruby 3 についての発表でした。 Ruby 3 の Static Analysis、Performance、Concurrency あたりの話を中心に、Ruby の今後の展望について語られました。普段 Ruby を使って仕事をしている身として、Matz さんから Ruby 3 の話を聞けたのは貴重な時間でしたし、改めて Ruby の進化を実感できるセッションでした。 Matz さんの Keynote その他のセッションスケジュールについてはこちら。 rubykaigi.org 2 階にはブースゾーンがあり、セッションの合間にはたくさんの参加者で溢れかえっていました。 ブースゾーンは大盛況 ブースゾーンの出入り口付近には各社のノベルティ Ruby 関連書籍の展示も 会場 5 階(最上階)にはハックスペースが用意されていました。 ここで各々休憩したり、黙々と作業したり、仲間と談笑したりと、様々な用途に使われていました。 ハックスペース入り口 ハックスペースの中(このときはセッション中だったので空いてました) 福岡開催ならではの屋台スペースも用意されていました。 ランチタイムには屋台ラーメンなどが振る舞われ、めちゃくちゃ混み合っていましたが、こういう地域特有の催しは RubyKaigi を盛り上げてくれるので良いですね。 ランチ前になるとゾロゾロと人集りが ランチタイムの屋台は大行列 屋台でラーメンを食らう参加者を羨むエンジニア中畑 メドレーブースの様子 また、2 階のブースゾーンにはメドレーのブースも出展しました。 今回参加したメンバー全員で ノベルティーにはメドレーロゴ付きのうちわ、ステッカー、お水、そして恒例の絆創膏を用意しました。 RubyKaigi 2018 でもらったメドレーの絆創膏が、子供が怪我したときに役に立ったよ〜という嬉しいお声をいただいたりもしました。 靴擦れや擦り傷を負ったとき、お子さんが転んだときとかに役に立つので、今度見かけた際はぜひお持ち帰りください。 メドレーの絆創膏 ブースではメドレーの会社説明やメドレーが提供するサービスの説明などを行いました。 スポンサーとして初参加だった RubyKaigi 2017 に参加したときよりもメドレーのことを知っている人が増えているなあと実感しました。 ブースで対応するエンジニア達(中畑、稲本、橋本) Matz さんにも来ていただきました! 福岡の様子 そして福岡といえば美味しいごはんですよね。 1 日目の夜は RubyKaigi 2019 Official Party が開催され、中洲川端商店街を半貸切にして日本酒やうどん、ラーメンや地鶏などが振る舞われました。 RubyKaigi 2019 Official Party の会場・中洲川端商店街の Guide Map 大樽に入って日本酒が配られてました 日本酒のラインナップ  うどんを前に満面の笑みの広報・深澤 夜は福岡の美食を求めて街に繰り出しました。 絶品イカの活造り 定番モツ鍋 出汁が最高の水炊き 会場近くの某有名ラーメン店のきくらげラーメン あまりのうまさに昇天するエンジニア中畑 また、RubyKaigi 初参加の 2017 年から続けている神社参拝にも行ってきました。 今回は警固神社(けごじんじゃ)に参拝してきました。 kegojinja.or.jp 警固神社入り口 参拝するエンジニア中畑 さいごに 2017 年から 3 度目となる RubyKaigi の協賛の様子をお届けしました。 Breakfast Sponsor として、RubyKaigi 参加者のみなさんにご満足いただけて本当に良かったなあと思います。 繰り返しになりますが、Ruby と Ruby コミュニティの発展のため、今後も様々な形で貢献していければと思います。 来年 2020 年は長野県松本市での開催ということで、またみなさんとお会いできることを願って、レポートを締めたいと思います。 rubykaigi.org お知らせ メドレーでは医療業界に存在する課題に IT を駆使して取り組んでいきたいメンバーを、デザイナー・エンジニアを中心に全職種絶賛募集中です。皆さまからのご応募お待ちしております。 www.medley.jp
こんにちは。開発本部のエンジニア・新居です。 メドレーは 4/18〜4/20 に開催された RubyKaigi 2019 に Breakfast Sponsor(朝食スポンサー)として協賛させていただきました( 一昨年の Ruby Sponsor 、 昨年の Lightning Talks Sponsor に続き、3 年目の協賛です)。 rubykaigi.org 2017 年のレポート developer.medley.jp 2018 年のレポート developer.medley.jp 2019 年は福岡県の福岡国際会議場での開催でした。会場に向かう途中の博多駅ではさっそく RubyKaigi のポスターに迎えられ、RubyKaigi ムードが高まっておりました。 博多駅ではさっそく RubyKaigi のポスターがお出迎え ということで、今年の RubyKaigi の様子をレポートさせていただきます。 www.marinemesse.or.jp Breakfast Sponsor の様子 今回は Breakfast Sponsor としての協賛で、RubyKaigi2 日目と 3 日目の朝 8 時 30 分から 10 時までの時間帯で、RubyKaigi に参加されるみなさんに朝食をご提供させていただきました。 朝食会場は福岡国際会議場内の 1F にあるレストラン ラコンテ さん。朝食の内容はビュッフェ形式で、焼き魚やオムレツなどの定番おかずと、福岡名産の辛子明太子や辛子高菜をたらふく食べられる朝食でした。 入り口でみなさんをお出迎えするエンジニア稲本 おしゃれなテラス席 ビュッフェに並ぶおかず フルーツもたくさん 「辛子明太 & 辛子高菜」乗せごはん 福岡名産の辛子明太子と辛子高菜を白ごはんに添えてたらふくいただきました 会場の様子、大盛況でした テラス席はグローバルな感じ Twitter でも朝食の様子を話題にしていただけたりと、ご満足いただけた様子が伺えました。 MEDLEY さんの朝食サービス、めっちゃメニューある。外で優雅に食べてます — Tsukasa OISHI (@tsukasa_oishi) April 18, 2019 MEDLEY さん提供の朝食はブュッフェ形式。洋風にしてみたけど、他にご飯や味噌汁もある。 #rubykaigi pic.twitter.com/W4eggL6PQt — thinca (@thinca) April 19, 2019 RubyKaigi と MEDLEY さんのおかげで健康的な生活してる…。 #rubykaigi pic.twitter.com/Z502pk3yKg — yebis0942 (@yebis0942) April 19, 2019 朝食で食べた明太子・高菜ご飯がおいしかった! MEDLEY さん、ありがとうございます! #rubykaigi — snagasawa (@snagasawa_) April 20, 2019 ご来場いただいた人数は、RubyKaigi2 日目(朝食 1 日目)は 379 名、3 日目(朝食 2 日目)は 411 名でした。 朝食会場の出入り口でご案内していると「美味しかったです、ありがとうございました!」というお声を直接いただけたりと、みなさんにご満足いただけたようで良かったです。 Breakfast Sponsor での参加は初めてでしたが、みなさんが満足気に朝食会場を後にする姿を見ているとこちらも嬉しい気持ちになりました。 朝食をご利用いただいたみなさん、本当にありがとうございました。 今年は Breakfast Sponsor という形でしたが、Ruby と Ruby コミュニティの発展のため、今後も様々な形で貢献していければと思います。 RubyKaigi 2019 の様子 今年も毎年恒例の Matz さんの Keynote から始まりました。 今年は「The Year of Concurrency」というテーマで、Ruby 3 についての発表でした。 Ruby 3 の Static Analysis、Performance、Concurrency あたりの話を中心に、Ruby の今後の展望について語られました。普段 Ruby を使って仕事をしている身として、Matz さんから Ruby 3 の話を聞けたのは貴重な時間でしたし、改めて Ruby の進化を実感できるセッションでした。 Matz さんの Keynote その他のセッションスケジュールについてはこちら。 rubykaigi.org 2 階にはブースゾーンがあり、セッションの合間にはたくさんの参加者で溢れかえっていました。 ブースゾーンは大盛況 ブースゾーンの出入り口付近には各社のノベルティ Ruby 関連書籍の展示も 会場 5 階(最上階)にはハックスペースが用意されていました。 ここで各々休憩したり、黙々と作業したり、仲間と談笑したりと、様々な用途に使われていました。 ハックスペース入り口 ハックスペースの中(このときはセッション中だったので空いてました) 福岡開催ならではの屋台スペースも用意されていました。 ランチタイムには屋台ラーメンなどが振る舞われ、めちゃくちゃ混み合っていましたが、こういう地域特有の催しは RubyKaigi を盛り上げてくれるので良いですね。 ランチ前になるとゾロゾロと人集りが ランチタイムの屋台は大行列 屋台でラーメンを食らう参加者を羨むエンジニア中畑 メドレーブースの様子 また、2 階のブースゾーンにはメドレーのブースも出展しました。 今回参加したメンバー全員で ノベルティーにはメドレーロゴ付きのうちわ、ステッカー、お水、そして恒例の絆創膏を用意しました。 RubyKaigi 2018 でもらったメドレーの絆創膏が、子供が怪我したときに役に立ったよ〜という嬉しいお声をいただいたりもしました。 靴擦れや擦り傷を負ったとき、お子さんが転んだときとかに役に立つので、今度見かけた際はぜひお持ち帰りください。 メドレーの絆創膏 ブースではメドレーの会社説明やメドレーが提供するサービスの説明などを行いました。 スポンサーとして初参加だった RubyKaigi 2017 に参加したときよりもメドレーのことを知っている人が増えているなあと実感しました。 ブースで対応するエンジニア達(中畑、稲本、橋本) Matz さんにも来ていただきました! 福岡の様子 そして福岡といえば美味しいごはんですよね。 1 日目の夜は RubyKaigi 2019 Official Party が開催され、中洲川端商店街を半貸切にして日本酒やうどん、ラーメンや地鶏などが振る舞われました。 RubyKaigi 2019 Official Party の会場・中洲川端商店街の Guide Map 大樽に入って日本酒が配られてました 日本酒のラインナップ  うどんを前に満面の笑みの広報・深澤 夜は福岡の美食を求めて街に繰り出しました。 絶品イカの活造り 定番モツ鍋 出汁が最高の水炊き 会場近くの某有名ラーメン店のきくらげラーメン あまりのうまさに昇天するエンジニア中畑 また、RubyKaigi 初参加の 2017 年から続けている神社参拝にも行ってきました。 今回は警固神社(けごじんじゃ)に参拝してきました。 kegojinja.or.jp 警固神社入り口 参拝するエンジニア中畑 さいごに 2017 年から 3 度目となる RubyKaigi の協賛の様子をお届けしました。 Breakfast Sponsor として、RubyKaigi 参加者のみなさんにご満足いただけて本当に良かったなあと思います。 繰り返しになりますが、Ruby と Ruby コミュニティの発展のため、今後も様々な形で貢献していければと思います。 来年 2020 年は長野県松本市での開催ということで、またみなさんとお会いできることを願って、レポートを締めたいと思います。 rubykaigi.org お知らせ メドレーでは医療業界に存在する課題に IT を駆使して取り組んでいきたいメンバーを、デザイナー・エンジニアを中心に全職種絶賛募集中です。皆さまからのご応募お待ちしております。 www.medley.jp
こんにちは。開発本部のエンジニア・新居です。 メドレーは 4/18〜4/20 に開催された RubyKaigi 2019 に Breakfast Sponsor(朝食スポンサー)として協賛させていただきました( 一昨年の Ruby Sponsor 、 昨年の Lightning Talks Sponsor に続き、3 年目の協賛です)。 rubykaigi.org 2017 年のレポート developer.medley.jp 2018 年のレポート developer.medley.jp 2019 年は福岡県の福岡国際会議場での開催でした。会場に向かう途中の博多駅ではさっそく RubyKaigi のポスターに迎えられ、RubyKaigi ムードが高まっておりました。 博多駅ではさっそく RubyKaigi のポスターがお出迎え ということで、今年の RubyKaigi の様子をレポートさせていただきます。 www.marinemesse.or.jp Breakfast Sponsor の様子 今回は Breakfast Sponsor としての協賛で、RubyKaigi2 日目と 3 日目の朝 8 時 30 分から 10 時までの時間帯で、RubyKaigi に参加されるみなさんに朝食をご提供させていただきました。 朝食会場は福岡国際会議場内の 1F にあるレストラン ラコンテ さん。朝食の内容はビュッフェ形式で、焼き魚やオムレツなどの定番おかずと、福岡名産の辛子明太子や辛子高菜をたらふく食べられる朝食でした。 入り口でみなさんをお出迎えするエンジニア稲本 おしゃれなテラス席 ビュッフェに並ぶおかず フルーツもたくさん 「辛子明太 & 辛子高菜」乗せごはん 福岡名産の辛子明太子と辛子高菜を白ごはんに添えてたらふくいただきました 会場の様子、大盛況でした テラス席はグローバルな感じ Twitter でも朝食の様子を話題にしていただけたりと、ご満足いただけた様子が伺えました。 MEDLEY さんの朝食サービス、めっちゃメニューある。外で優雅に食べてます — Tsukasa OISHI (@tsukasa_oishi) April 18, 2019 MEDLEY さん提供の朝食はブュッフェ形式。洋風にしてみたけど、他にご飯や味噌汁もある。 #rubykaigi pic.twitter.com/W4eggL6PQt — thinca (@thinca) April 19, 2019 RubyKaigi と MEDLEY さんのおかげで健康的な生活してる…。 #rubykaigi pic.twitter.com/Z502pk3yKg — yebis0942 (@yebis0942) April 19, 2019 朝食で食べた明太子・高菜ご飯がおいしかった! MEDLEY さん、ありがとうございます! #rubykaigi — snagasawa (@snagasawa_) April 20, 2019 ご来場いただいた人数は、RubyKaigi2 日目(朝食 1 日目)は 379 名、3 日目(朝食 2 日目)は 411 名でした。 朝食会場の出入り口でご案内していると「美味しかったです、ありがとうございました!」というお声を直接いただけたりと、みなさんにご満足いただけたようで良かったです。 Breakfast Sponsor での参加は初めてでしたが、みなさんが満足気に朝食会場を後にする姿を見ているとこちらも嬉しい気持ちになりました。 朝食をご利用いただいたみなさん、本当にありがとうございました。 今年は Breakfast Sponsor という形でしたが、Ruby と Ruby コミュニティの発展のため、今後も様々な形で貢献していければと思います。 RubyKaigi 2019 の様子 今年も毎年恒例の Matz さんの Keynote から始まりました。 今年は「The Year of Concurrency」というテーマで、Ruby 3 についての発表でした。 Ruby 3 の Static Analysis、Performance、Concurrency あたりの話を中心に、Ruby の今後の展望について語られました。普段 Ruby を使って仕事をしている身として、Matz さんから Ruby 3 の話を聞けたのは貴重な時間でしたし、改めて Ruby の進化を実感できるセッションでした。 Matz さんの Keynote その他のセッションスケジュールについてはこちら。 rubykaigi.org 2 階にはブースゾーンがあり、セッションの合間にはたくさんの参加者で溢れかえっていました。 ブースゾーンは大盛況 ブースゾーンの出入り口付近には各社のノベルティ Ruby 関連書籍の展示も 会場 5 階(最上階)にはハックスペースが用意されていました。 ここで各々休憩したり、黙々と作業したり、仲間と談笑したりと、様々な用途に使われていました。 ハックスペース入り口 ハックスペースの中(このときはセッション中だったので空いてました) 福岡開催ならではの屋台スペースも用意されていました。 ランチタイムには屋台ラーメンなどが振る舞われ、めちゃくちゃ混み合っていましたが、こういう地域特有の催しは RubyKaigi を盛り上げてくれるので良いですね。 ランチ前になるとゾロゾロと人集りが ランチタイムの屋台は大行列 屋台でラーメンを食らう参加者を羨むエンジニア中畑 メドレーブースの様子 また、2 階のブースゾーンにはメドレーのブースも出展しました。 今回参加したメンバー全員で ノベルティーにはメドレーロゴ付きのうちわ、ステッカー、お水、そして恒例の絆創膏を用意しました。 RubyKaigi 2018 でもらったメドレーの絆創膏が、子供が怪我したときに役に立ったよ〜という嬉しいお声をいただいたりもしました。 靴擦れや擦り傷を負ったとき、お子さんが転んだときとかに役に立つので、今度見かけた際はぜひお持ち帰りください。 メドレーの絆創膏 ブースではメドレーの会社説明やメドレーが提供するサービスの説明などを行いました。 スポンサーとして初参加だった RubyKaigi 2017 に参加したときよりもメドレーのことを知っている人が増えているなあと実感しました。 ブースで対応するエンジニア達(中畑、稲本、橋本) Matz さんにも来ていただきました! 福岡の様子 そして福岡といえば美味しいごはんですよね。 1 日目の夜は RubyKaigi 2019 Official Party が開催され、中洲川端商店街を半貸切にして日本酒やうどん、ラーメンや地鶏などが振る舞われました。 RubyKaigi 2019 Official Party の会場・中洲川端商店街の Guide Map 大樽に入って日本酒が配られてました 日本酒のラインナップ  うどんを前に満面の笑みの広報・深澤 夜は福岡の美食を求めて街に繰り出しました。 絶品イカの活造り 定番モツ鍋 出汁が最高の水炊き 会場近くの某有名ラーメン店のきくらげラーメン あまりのうまさに昇天するエンジニア中畑 また、RubyKaigi 初参加の 2017 年から続けている神社参拝にも行ってきました。 今回は警固神社(けごじんじゃ)に参拝してきました。 kegojinja.or.jp 警固神社入り口 参拝するエンジニア中畑 さいごに 2017 年から 3 度目となる RubyKaigi の協賛の様子をお届けしました。 Breakfast Sponsor として、RubyKaigi 参加者のみなさんにご満足いただけて本当に良かったなあと思います。 繰り返しになりますが、Ruby と Ruby コミュニティの発展のため、今後も様々な形で貢献していければと思います。 来年 2020 年は長野県松本市での開催ということで、またみなさんとお会いできることを願って、レポートを締めたいと思います。 rubykaigi.org お知らせ メドレーでは医療業界に存在する課題に IT を駆使して取り組んでいきたいメンバーを、デザイナー・エンジニアを中心に全職種絶賛募集中です。皆さまからのご応募お待ちしております。 www.medley.jp
みなさん、こんにちは。開発本部の平木です。 2017 年から、RubyKaigi にスポンサーとして参加していましたが、今年も 朝食スポンサー として協賛することになりました! (去年とおととしの参加レポート) RubyKaigi 2017 にメドレーが Ruby Sponsor として参加しました Lightning Talks Sponsor として RubyKaigi 2018 に参加してきました 会場である、福岡国際会議場内の 1F にあるレストラン ラコンテ さんでビュッフェ形式の朝食を楽しむことができます。 会期中の 4/19~20 日の 8:30 ~ 10:00 で開催しています。当日はメドレーメンバーがご案内する予定になっていますので、ぜひお気軽に話かけてください!目印として、メンバーはメドレーパーカーを着用しています。 メニューは和洋それぞれ用意があり、福岡ならではのメニューも入っていますので、1 日の始まりにぜひおいしい朝食を食べて元気にセッションに臨んでください。 また、スポンサーブース内にもメドレーブースが常設されており、エンジニア 4 人も行く予定となっていますので、ぜひお立ち寄りいただいて、みなさんと交流できればと思います。 それでは、RubyKaigi という大きなイベントでまた皆様にお会いできるのを楽しみにしています!!
みなさん、こんにちは。開発本部の平木です。 2017 年から、RubyKaigi にスポンサーとして参加していましたが、今年も 朝食スポンサー として協賛することになりました! (去年とおととしの参加レポート) RubyKaigi 2017 にメドレーが Ruby Sponsor として参加しました Lightning Talks Sponsor として RubyKaigi 2018 に参加してきました 会場である、福岡国際会議場内の 1F にあるレストラン ラコンテ さんでビュッフェ形式の朝食を楽しむことができます。 会期中の 4/19~20 日の 8:30 ~ 10:00 で開催しています。当日はメドレーメンバーがご案内する予定になっていますので、ぜひお気軽に話かけてください!目印として、メンバーはメドレーパーカーを着用しています。 メニューは和洋それぞれ用意があり、福岡ならではのメニューも入っていますので、1 日の始まりにぜひおいしい朝食を食べて元気にセッションに臨んでください。 また、スポンサーブース内にもメドレーブースが常設されており、エンジニア 4 人も行く予定となっていますので、ぜひお立ち寄りいただいて、みなさんと交流できればと思います。 それでは、RubyKaigi という大きなイベントでまた皆様にお会いできるのを楽しみにしています!!
みなさん、こんにちは。開発本部の平木です。 2017 年から、RubyKaigi にスポンサーとして参加していましたが、今年も 朝食スポンサー として協賛することになりました! (去年とおととしの参加レポート) RubyKaigi 2017 にメドレーが Ruby Sponsor として参加しました Lightning Talks Sponsor として RubyKaigi 2018 に参加してきました 会場である、福岡国際会議場内の 1F にあるレストラン ラコンテ さんでビュッフェ形式の朝食を楽しむことができます。 会期中の 4/19~20 日の 8:30 ~ 10:00 で開催しています。当日はメドレーメンバーがご案内する予定になっていますので、ぜひお気軽に話かけてください!目印として、メンバーはメドレーパーカーを着用しています。 メニューは和洋それぞれ用意があり、福岡ならではのメニューも入っていますので、1 日の始まりにぜひおいしい朝食を食べて元気にセッションに臨んでください。 また、スポンサーブース内にもメドレーブースが常設されており、エンジニア 4 人も行く予定となっていますので、ぜひお立ち寄りいただいて、みなさんと交流できればと思います。 それでは、RubyKaigi という大きなイベントでまた皆様にお会いできるのを楽しみにしています!!
みなさん、こんにちは。開発本部の平木です。 2017 年から、RubyKaigi にスポンサーとして参加していましたが、今年も 朝食スポンサー として協賛することになりました! (去年とおととしの参加レポート) RubyKaigi 2017 にメドレーが Ruby Sponsor として参加しました Lightning Talks Sponsor として RubyKaigi 2018 に参加してきました 会場である、福岡国際会議場内の 1F にあるレストラン ラコンテ さんでビュッフェ形式の朝食を楽しむことができます。 会期中の 4/19~20 日の 8:30 ~ 10:00 で開催しています。当日はメドレーメンバーがご案内する予定になっていますので、ぜひお気軽に話かけてください!目印として、メンバーはメドレーパーカーを着用しています。 メニューは和洋それぞれ用意があり、福岡ならではのメニューも入っていますので、1 日の始まりにぜひおいしい朝食を食べて元気にセッションに臨んでください。 また、スポンサーブース内にもメドレーブースが常設されており、エンジニア 4 人も行く予定となっていますので、ぜひお立ち寄りいただいて、みなさんと交流できればと思います。 それでは、RubyKaigi という大きなイベントでまた皆様にお会いできるのを楽しみにしています!!
みなさん、こんにちは。開発本部の平木です。 2017 年から、RubyKaigi にスポンサーとして参加していましたが、今年も 朝食スポンサー として協賛することになりました! (去年とおととしの参加レポート) RubyKaigi 2017 にメドレーが Ruby Sponsor として参加しました Lightning Talks Sponsor として RubyKaigi 2018 に参加してきました 会場である、福岡国際会議場内の 1F にあるレストラン ラコンテ さんでビュッフェ形式の朝食を楽しむことができます。 会期中の 4/19~20 日の 8:30 ~ 10:00 で開催しています。当日はメドレーメンバーがご案内する予定になっていますので、ぜひお気軽に話かけてください!目印として、メンバーはメドレーパーカーを着用しています。 メニューは和洋それぞれ用意があり、福岡ならではのメニューも入っていますので、1 日の始まりにぜひおいしい朝食を食べて元気にセッションに臨んでください。 また、スポンサーブース内にもメドレーブースが常設されており、エンジニア 4 人も行く予定となっていますので、ぜひお立ち寄りいただいて、みなさんと交流できればと思います。 それでは、RubyKaigi という大きなイベントでまた皆様にお会いできるのを楽しみにしています!!
みなさん、こんにちは。開発本部の平木です。 2017 年から、RubyKaigi にスポンサーとして参加していましたが、今年も 朝食スポンサー として協賛することになりました! (去年とおととしの参加レポート) RubyKaigi 2017 にメドレーが Ruby Sponsor として参加しました Lightning Talks Sponsor として RubyKaigi 2018 に参加してきました 会場である、福岡国際会議場内の 1F にあるレストラン ラコンテ さんでビュッフェ形式の朝食を楽しむことができます。 会期中の 4/19~20 日の 8:30 ~ 10:00 で開催しています。当日はメドレーメンバーがご案内する予定になっていますので、ぜひお気軽に話かけてください!目印として、メンバーはメドレーパーカーを着用しています。 メニューは和洋それぞれ用意があり、福岡ならではのメニューも入っていますので、1 日の始まりにぜひおいしい朝食を食べて元気にセッションに臨んでください。 また、スポンサーブース内にもメドレーブースが常設されており、エンジニア 4 人も行く予定となっていますので、ぜひお立ち寄りいただいて、みなさんと交流できればと思います。 それでは、RubyKaigi という大きなイベントでまた皆様にお会いできるのを楽しみにしています!!
みなさん、こんにちは。開発本部の平木です。 2017 年から、RubyKaigi にスポンサーとして参加していましたが、今年も 朝食スポンサー として協賛することになりました! (去年とおととしの参加レポート) RubyKaigi 2017 にメドレーが Ruby Sponsor として参加しました Lightning Talks Sponsor として RubyKaigi 2018 に参加してきました 会場である、福岡国際会議場内の 1F にあるレストラン ラコンテ さんでビュッフェ形式の朝食を楽しむことができます。 会期中の 4/19~20 日の 8:30 ~ 10:00 で開催しています。当日はメドレーメンバーがご案内する予定になっていますので、ぜひお気軽に話かけてください!目印として、メンバーはメドレーパーカーを着用しています。 メニューは和洋それぞれ用意があり、福岡ならではのメニューも入っていますので、1 日の始まりにぜひおいしい朝食を食べて元気にセッションに臨んでください。 また、スポンサーブース内にもメドレーブースが常設されており、エンジニア 4 人も行く予定となっていますので、ぜひお立ち寄りいただいて、みなさんと交流できればと思います。 それでは、RubyKaigi という大きなイベントでまた皆様にお会いできるのを楽しみにしています!!