まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

タグ:oauth

このブログエントリの続きです:
Slack の OAuth API を使ってみる

↑ここで紹介した方法を使って実際にアプリケーション・サービスを作ってみました。作った内容はこれ↓の Slack 版です:
お絵かき LIFF アプリを作ってみた

2019052501


(実はもともとは Twitter 向けに作ったのですが)LINE のフロントエンドフレームワーク: LIFF を使って、その場で指でお絵描きした画像を LINE のトークルームに送信する、という連携アプリケーションを以前に作りました。その Slack への移植です。

なお、このアプリケーションは Barloon というエンジニア向けバーで企画されたハッカソン向けに作成しました。興味ある方は "Barloon" でググって調べてみてください。


【作った物】
こちらで MIT ライセンスで公開しています。よかったら使ってください:
https://github.com/dotnsf/slack-doodle

2019052502



以下でも紹介していますが、注意点として「ワークスペースごとにアプリケーション・サーバーが1台必要」です。その理由ですが、このアプリは Slack API を利用して作っているのですが、Slack API に登録アプリを申請する際にワークスペース(https://○○○○.slack.com/ の ○○○○部分)を指定して申請する必要があるからです。ここで申請したワークスペース向けにアプリケーションを作って動かす形になるため、複数のワークスペースで動くアプリケーションを1つの URL で動かすことができないのでした(このあたりが上記の LINE 向けアプリと異なります)。


【サーバーの動かし方】
このアプリケーションは Node.js 上で動くウェブアプリケーションです。一応レスポンシブ対応しているつもりなので、PC ブラウザからも、スマホのブラウザからも使えます(PC ブラウザの場合はマウスで、スマホブラウザの場合は指でお絵描きすることになります)。したがって Node.js が導入済みのアプリケーション・サーバーが必要です。

利用にあたっては、まず Slack API のアプリケーション登録が必要です。こちらの詳しい手順はこのリンク先を参照してください:
http://dotnsf.blog.jp/archives/1074688701.html

ただし1点だけ注意が必要です。上記ページではアプリケーションの scope に channels:read のみを指定していますが、このお絵描きアプリケーションでは更に加えて:
 chat:write:user
 files:write:user
の2つ(計3つ)の scope を指定する必要があります(描いた画像を API でアップロードするために必要な scope です)。この3つを scope に指定する必要がある、という点に注意してください。

2019052503

※必要に応じてアプリケーションのアイコンなども好きなものに変えておいてください。


その上で上記 github の URLからソースコード一式を Node.js アプリケーションサーバー上に git clone するか download & unzip して、ソースコードを展開します。

展開後、settings.js というファイルが存在しているので、このファイルをテキストエディタで開き、exports.slack_client_id の値と、exports.slack_client_secret の値をそれぞれ Slack API 登録アプリの client_id および client_secret の値に書き換えて保存します(このあたりの具体的な情報はこちらを参照してください)。

そしてアプリケーションサーバーを起動、これで準備完了です:
$ npm install
$ node app

【遊び方】
アプリケーション・サーバー(例えば https://slack-doodle.xxx.com/ )が動いている状態で、そのアプリケーションサーバーの URL に PC かスマホのブラウザにアクセスするだけなのですが、その前にやっておくことがあります。

上記でも触れたのですが、このアプリケーションサーバーは特定のワークスペース向けに作られています(そのワークスペースでしか使えません)。一方、ブラウザで Slack にアクセスすると、いろんなワークスペースに切り替えて使うことができます。ということはブラウザが目的のワークスペース以外のセッションなどを保持している可能性があり、その状態で使っても期待通りの挙動にならない可能性があるのです。

この状態をクリアするために『念の為』以下の手順を最初に行っておくことを推奨します。まず PC かスマホのブラウザを起動し、目的のワークスペース(例えば目的のワークスペースが "abc" であれば https://abc.slack.com/ )にアクセスして、認証してログインします。これでブラウザが目的のワークスペースのセッションを保持した状態が作れました。

その上で、そのままアプリケーションサーバー( https://slack-doodle.xxx.com/ )にアクセスします。以下はスマホでの画面例ですが、PCブラウザだともう少し横に大きな画面になると思います(一応、この未ログインの時点でお絵描きを試すことはできるのですが、送信することはできません)。ではログインするため左上の "Login" をタップします:
2019052504


Slack アプリケーションのページに転送され、目的のワークスペースに向けた OAuth の認証が行われます:
2019052505


内容を確認して、「許可する」を選択します:
2019052506


するとログインが完了し、元のアプリの画面に戻ります。この時、画面上部にワークスペース上で自分が利用することのできるチャネルが選択できるようになり、POST をクリックすると、ここで選択したチャネルに描いた画像がアップロードされます:
2019052507


実際に POST するとこんな感じで目的のワークスペースの目的のチャネルに画像をアップロードすることができます:
2019052508


この系統のアプリ、Twitter ではじめて、LINE に移植して、今回は Slack にも移植して・・・ 次は何にしよう?? ちなみに facebook は publish の API が昨年廃止になってしまったので技術的に作れないことがわかってます。



某アプリを Slack 対応する経緯で Slack API の中の、特に認証/認可を司る OAuth API を使う機会があったので自己まとめです。

もともとやりたかったのはウェブアプリに Slack アカウントでログインして、そのログインした人の権限でチャネル一覧を取得し(※)、ウェブアプリから指定したチャネルにメッセージを書き込む、ということでした。この中の※部分までを Node.js + Express + EJS で実現したコードを Github に公開しています(後述)。


実際に試してみるにはまず Slack に対象アプリケーションを登録する必要があります。 https://api.slack.com/apps を開いてログインし、"Create New App" ボタンをクリックしてウェブアプリを登録します:
2019052401


登録するアプリの名前と、対象ワークスペースを指定します(つまり同じアプリを複数のワークスペースで使いたい場合は、アプリを複数登録する必要があります)。以下では名前は "Slack OAuth Sample"、ワークスペースは "dotnsf" を指定しています(ワークスペースはログインしたユーザーが利用可能なワークスペース一覧から選択します)。最後に "Create App" ボタンをクリックして作成します:
2019052402


すると指定したアプリケーションの API 設定画面に切り替わります。画面左上に入力したアプリ名がデフォルトアイコンと一緒に表示されていて、"Basic Information" メニューが選択されていることを確認します:
2019052403


この画面を下スクロールすると App Credentials という項目があります。この中の Client IDClient Secret の値を後で使うので、どこかにコピーしておくか、いつでもこの画面を開ける状態にしておきましょう。なお Client ID の値は画面内に表示されていますが、Client Secret の値は初期状態では非表示になっています。"Show" ボタンをクリックして内容を表示し、その表示された値をあとで使うことに注意してください。またこれらの値は他の人には教えないように、自分で管理する必要があります:
2019052404


次に画面左のメニューから "OAuth & Permissions" を選び、少し下にスクロールすると Redirect URLs という項目があります。ここにウェブアプリケーションを動かす際のコールバック URL を登録しておく必要があります。"Add New Redirect URL" ボタンをクリックします:
2019052405


すると Redirect URL を追加する画面になるので、http(s)://サーバー名/slack/callback と入力します。この値は開発時には開発時用のサーバー名とポート番号、本番環境では本番環境用のサーバー名を指定する必要があります。下図では開発時向けに localhost の 6010 番ポートで動かす想定で http://localhost:6010/slack/callback と指定しています。ここの値は実際の環境に合わせて適宜変更してください。入力し終わったら "Add" ボタンをクリックして、その後 "Save URLs" ボタンをクリックします:
2019052406


画面上部に "Success!" というメッセージが表示されればリダイレクト URL の設定は完了です。正しい Redirect URLs が登録されたことを確認します:
2019052407


続けて、このアプリで利用する Slack 機能のスコープを指定します。実は OAuth 認証だけであればここの設定は不要なのですが、今回のデモアプリでは OAuth 認証後にログインユーザーが参照できるチャネルの一覧を取得して表示する、という機能が含まれています。また実際のアプリケーションではそのアプリケーションで実装する機能によって、ここでスコープを追加する必要があります:
2019052408


今回はログインユーザーが利用できるチャネル一覧を取得するため、"channels:read" スコープを追加します。また他に必要なスコープがあればここで追加します。最後に "Save Changes" ボタンをクリックして変更を反映します:
2019052409


これで Slack API 側の設定は完了しました。

では改めて Github からアプリケーションを取得します。Node.js がインストール済みの実行サーバー上で以下の URL を指定して git clone するか、ソースコードをダウンロード&展開してください:
 https://github.com/dotnsf/slack-oauth

2019052410


ソースコード内の settings.js をテキストエディタで開き、exports.slack_client_id の値と exports.slack_client_secret の値を上記で確認した client_id と client_secret の値に(コピー&ペーストなどで)変更して、保存してください。

なお、このサンプルアプリケーションでは以下のリクエスト API(?)が用意されていて、これらを明示的&内部的に使って動きます:
リクエスト API用途
GET /ユーザーがアクセスする唯一のページ。アクセス時に認証情報がセッションに含まれているとチャネル一覧が表示される。認証情報がセッションに含まれていない場合は認証前とみなして「ログイン」ボタンを表示する
GET /slack/loginユーザーページで「ログイン」ボタンをクリックした時に実行される。Slack の OAuth 認証ページにリダイレクトされる
GET /slack/callbackSlack の OAuth 認証ページで Authorize された時のリダイレクトページ。この URL が Slack OAuth 設定時に指定されている必要がある。アクセストークンを暗号化してセッションに保存し、GET / へリダイレクトされる
POST /slack/logoutログアウト(セッション情報を削除)する
GET /channelsチャネル一覧を取得する。認証後にユーザーページが表示されると内部的にこの REST API が AJAX 実行されて、画面にチャネル一覧が表示される。


では実際に起動してみます。起動サーバーにログインし、ソースコードのあるフォルダに移動した状態で、以下を実行します:
$ npm install
$ node app

そしてウェブブラウザで起動中のアプリケーションにアクセスします。以下の例では localhost:6010 でアプリケーションが起動されている想定になっているので、http://localhost:6010/ にアクセスします。上記の GET / が実行され、ログイン前のシンプルなページが表示されます。ここで "Login" を選択します:
2019052411


GET /slack/login が実行され、ブラウザは Slack API の OAuth 認証ページにリダイレクトされます。アプリケーションが利用する scope が表示され、このまま認証処理を許可するかどうかを聞かれます。許可する場合は "Authorize" を選択します:
2019052412


Authorize を選択すると認証と認可が完了し、そのアクセストークンが GET /slack/callback へ渡されます。そこでアクセストークンを暗号化してセッションに含めます。この状態であらためてトップページ(GET /)が表示され、ログイン処理が住んでいるのでログイン後の画面が表示されます。AJAX で GET /channels が実行され、ログインユーザーが参照することのできるチャネルの一覧が表示されれば成功です:
2019052413


以上、Slack API の OAuth を使ってウェブアプリケーションから Slack の認証を行い、認証ユーザーの権限で Slack API を外部から実行する、というアプリケーションのサンプルを作って実行するまでの手順紹介でした。


 

IBM Bluemix の利用料金は Bluemix ログイン後にアカウントメニューの「使用状況ダッシュボード」から確認することができます:
2016120801


組織とデータセンターの地域を指定して課金対象を絞りこむことができます。以下は月毎の推移グラフ:
2016120802


下にスクロールすると現在の月の、現時点での消費額を確認することもできます:
2016120803


さて、これらは利用料金を Bluemix のウェブコンソールにログインした上で確認する、という手順です。この内容を Bluemix のウェブコンソールを使わずに API で取得する方法は・・・ ありました!以下に Billing API を使って外部から利用料金を確認する手順を紹介します。

Billing API を実行する上で、以下の情報を指定する必要があります:
(1) 対象組織の GUID
(2) 対象地域(データセンター)
(3) 対象年月(YYYY-MM)
(4) OAuth トークン

(2) と (3) は指定するだけですが、(1) の組織 GUID と (4) の OAuth トークンはあらかじめ調べておく必要があります。仮に (2) はアメリカ南部("us-south")、(3) は 2016-11 を指定するものと仮定しておきます。


(1) の GUID は cf ツールを使って調べます。まずは利用料金を調べたい地域の API サーバーに cf ツールでログインします(下の例では US データセンターを指定しています):
$ cf login -a https://api.ng.bluemix.net/ -u (ユーザーID)

対象とする組織の名称(ID)がわかっている場合は不要ですが、組織 ID を確認する場合は "cf orgs" コマンドを実行します。ログインした ID で利用中の組織 ID の一覧が表示されます:
$ cf orgs

組織 ID が確認できている場合は、以下のコマンドでその組織の GUID を取得できます:
$ cf org (組織ID) --guid


次に (4) の OAuth トークンを取得します。これは同様に cf ツールで "cf oauth-token" コマンドを実行します。すると "bearer " から始まるトークン文字の羅列が戻ってきます。これが OAuth トークンです:
$ cf oauth-token
bearer XXXXXXXXXX....(文字の羅列)....XXXXXXXXXX

これで (1), (2), (3), (4) 全ての情報が揃いました。これらの情報を使って目的月(今回は 2016-11)の利用料金をコマンドラインから調べてみます。実行コマンドと、その実行結果(の一部)は以下のようになります:
$ curl -v -X GET -H "Authorization: bearer (OAuth トークン文字列)" "https://rated-usage.ng.bluemix.net/v2/metering/organizations/us-south:(組織 GUID)/usage/2016-11" | python -m json.tool

{
  "organizations": [
    {
      "billable_usage": {
        "spaces": []
      },
      "country_code": "JPN",
      "currency_code": "JPY",
      "id": "********-****-****-****-************",
      "name": "dotnsf@jp.ibm.com",
      "non_billable_usage": {
        "spaces": [
          {
            "applications": [],
            "containers": [],
            "id": "********-****-****-****-************",
"name": "********-****-****-****-************",
"services": [ { "id": "********-****-****-****-************",
"instances": [ { "id": "********-****-****-****-************",
"name": "IBM Insights for Twitter-5b", "plan_id": "********-****-****-****-************",
"usage": [ { "applicationId": "********-****-****-****-************",
"cost": 0, "name": "dotnsf-php-20161026", "quantity": 22066, "unit": "TWEET", "unitId": "TWEETS_PER_MONTH" } ] } ], "name": "twitterinsights" } ] }, { "applications": [ { "id": "********-****-****-****-************",
"name": "dotnsf-cloudant", "usage": [ { "buildpack": "********-****-****-****-************",
"cost": 2557.8000000000002, "quantity": 348, "runtime": { "id": "********-****-****-****-************",
"name": "liberty-for-java_v3_2-20160822-2200" }, "unit": "GB-HOURS", "unitId": "GB_HOURS_PER_MONTH" } ] }, : :

青字部分が実行コマンドで、その下が実行結果です。実行結果のところどころに "cost": ***** という形で各ランタイムやサービスごとの料金が表示されていることがわかります。

というわけで、この API を使うことで Bluemix の利用料金をコマンドラインから参照する、ことが実現できそうです。


(参考)
http://theblasfrompas.blogspot.jp/2016/02/invoking-billing-api-for-bluemix-public.html

久しぶりに Twitter API キーやアクセストークンを新規に取得しようとしたら、それまで知っていた手順と違っていたので、改めて書き残しておきます。

まず以下のサイトへ行きます。ログインしていない場合は右上に "Sign in" というリンクが表示されるので、そこからログインします:
Twitter Application Management


Twitter Application Management サイトにログインすると、自分が過去に作った Twitter アプリの一覧が表示されます(まだ作ったことがない場合は何も表示されないはずです)。新たに API キーを取得するには新しいアプリを1つ定義します。画面右上の "Create New App" と書かれたボタンをクリックします:
2015111101


新規に作成するアプリケーションの概要を入力します。このうち "Name" はアプリケーションの名称ですが、全半角スペースを含むことができません。また、既に誰かが使っている名称を使うこともできません。1語の単語の形でユニークな名称を指定してください。"Description" はアプリケーションの説明文ですが、空にはできません。"WebSite" はアプリケーションのウェブサイト URL でこれも必須ですが、Streaming API などウェブサイトの存在しないアプリを作る場合もあると思います。ここは http://127.0.0.1 で始まるような名前を指定しても動作には支障なさそうでした。Callback URL は OAuth のコールバック先ですが、必須ではありません:
2015111102


全て入力したら下にスクロールして、Developer Agreement を確認し、内容に同意できる場合は "Yes, I agree" にチェックを入れて、最後に "Create you Twitter application" ボタンをクリックします:
2015111103


指定したアプリケーションの API キーが作成されます。API キーを確認するには、"Keys and Access Tokens" タブを開くと、その中に API Key や API Secret などが表示されているはずです:
2015111104


一方、アクセストークンはこの段階ではまだ作成されていないはずです。アクセストークンが必要な場合はこのページを下にスクロールして、まだ作成されていないことを確認した上で "Create my access token" ボタンをクリックします:
2015111101


処理が成功すると同ページの内容が書き換わり、アクセストークンとアクセストークンシークレットが確認できるようになります:
2015111102



以前の方法だと、最初は https://dev.twitter.com/ からスタートしたような記憶があるんだけど、今はそこからだと API Key 取得ページへのリンクが見当たらないんだよな、、変わったのかな?


IBM のパブリック PaaS サービスである Bluemix を利用する上では、まず IBM ID ※と呼ばれるアカウントを取得する必要があります。そして IBM ID とパスワードでサービスにログインすることで、各種インスタンスを生成したり、設定変更したり、・・・というオペレーションが可能になります。

※正確には「Bluemix 用の IBM ID」と言うべきだと思ってます。


この IBM ID を自分のアプリケーションの認証として使うことができれば、わざわざユーザーディレクトリを別途用意する必要がなく、アプリケーションを「IBM ID でログインして使う」ということが可能になります。またこれができれば、例えば2つの異なるアプリケーションで共通のユーザーディレクトリを使いたい時にも、2つのユーザーディレクトリを用意する必要がなく、IBM IDという共通のアカウントを使えば(そしてアプリケーションの認証を IBM ID を使って実装すれば)できちゃうことになります。PaaS の環境にこのようなユーザーディレクトリまで用意されているのは便利ですね。 というわけで、今回は Bluemix 環境で SSO サービスを使ったアプリケーションを開発する方法の紹介をします。

まず(普通に)IBM IDで IBM Bluemix 環境にログインし、アプリケーションを1つ作成します(このアプリケーションで SSO サービスを使うことになります)。ここでは bluemixsso.mybluemix.net というホスト名でアプリケーションサーバーを作成しています。
2014071401a


そしてこのアプリケーションに SSO サービスをバインドします。ここまではデータベースサービスをバインドするような手順と同じです。
2014071401b

Single Sign On サービスを選択して、作成したアプリケーションにバインドします:
2014071401c


次に SSO サービスを REST API で使うためのエンドポイントを確認します。アプリケーションのページを開いて、その内の Single Sign On サービスパーツの "Show Credentials" をクリックします。
2014071403


このようなテキストフィールドが開いて、JSON テキストが表示されます:
2014071404


ここで表示される JSON テキストは以下のようになっています。この赤字部分(authorize_url, token_url, profile_resource の3つの値)を後で使うのでメモしておきます:
{
  "single.sign.on" : [ {
    "name" : "Single Sign On -5q",
    "label" : "single.sign.on",
    "plan" : "beta",
    "credentials" : {
      "profile_resource" : "https://idaas.ng.bluemix.net/idaas/resources/profile.jsp",
      "tokeninfo_resource" : "https://idaas.ng.bluemix.net/idaas/resources/tokeninfo.jsp",
      "openidProviderURL" : "https://idaas.ng.bluemix.net/idaas/openid",
      "token_url" : "https://idaas.ng.bluemix.net/sps/oauth20sp/oauth20/token",
      "authorize_url" : "https://idaas.ng.bluemix.net/sps/oauth20sp/oauth20/authorize"
    }
  } ]
}

次に SSO の Credential 情報を設定します。同じ画面の左ペインから "SERVICES" - "Single Sign On" をクリックします。画面右に現在の(初期状態の)SSO の設定内容が編集可能な状態で表示されます:
2014071405


以下のように編集して、最後に "Save" ボタンをクリックします:
 Identity Providers: "IBM" にチェック
 Authentication Protocol: "OAuth 2.0" を選択
 Display Name: ユーザーの画面に表示されるアプリケーション名称を指定
 Enabled: チェック
 Redirect URI: アプリケーションの OAuth リダイレクトURI (後述)を指定
2014071406


認証方法には OpenID か OAuth2.0 かを選ぶことができますが、今回は OAuth2.0 にしています。またその Provider に "IBM" を選ぶことで IBM ID を使った OAuth を指定していることになります。

入力内容に不備がなければ保存され、画面には "Client Identifier" と "Client Secret" という2つの値が表示されるはずです。この2つの値も後で(OAuth の認証時に)使うのでメモしておきます。
2014071407


ここまでの作業でサービス側の準備はできました。では次にこの SSO を実際に使って OAuth でログインするアプリケーションの実装方法を紹介します。なお、以下の例では Java および JavaScript を使って実装していますが、API そのものは REST を使うので他の言語でも同様の処理を記述すれば実装できると思います。

なお、今回はログイン後のページの URL(上記のRedirect URI) を http://localhost:8080/BluemixSSO/index.jsp として SSO で設定しています。あくまで localhost を使った開発環境での設定であり、本番稼働時にはここをhttp://bluemixsso.mybluemix.net/index.jsp という値に書き換える必要があります。ただ今回の紹介ではあくまで開発環境上だけでの稼働確認を行うためこの値にしています。適宜変更して利用してください。


まずはログイン前のページを用意します。ログイン後のページと同じページにしてもいいのですが、いろいろ面倒なのでログイン前は login.html、ログイン後は index.jsp というページが表示されるものとします。

で、ログイン前のページはこのような感じにします。このサンプルでは単純にログインボタンがあるだけです:
<html>
<head>
<title>ログイン前</title>
<script type="text/javascript">
var client_identifier = "(Client Identifierの値)";
//var client_secret = "(Client Secretの値)";
var server_url = "http://localhost:8080/BluemixSSO/index.jsp";
function login(){
  // authorize_url へリクエスト
  location.href = "https://idaas.ng.bluemix.net/sps/oauth20sp/oauth20/authorize?client_id=" + client_identifier + "&redirect_uri=" + server_url + "&scope=profile&response_type=code";
}
</script>
</head>
<body>
<input type="button" value="ログイン" onClick="login();"/>
</body>
</html>

このページ内のボタンをクリックすると JavaScript が実行されて、authorize_url に対してパラメータを付けてリクエストが実行されます。成功すると Redirect URL で指定した URL(http://localhost:8080/BluemixSSO/index.jsp) にアクセスコードが付与された形でリダイレクトされます。

そしてリダイレクト先(index.jsp)では以下の様なコードを用意しておきます:
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<@ page import="javax.servlet.http.*" %>
<@ page import="java.util.*" %>
<@ page import="java.io.*" %>
<@ page import="java.net.*" %>
<@ page import="java.util.*" %>
<@ page import="org.apache.commons.httpclient.*" %>
<@ page import="org.apache.commons.httpclient.methods.*" %>

<% request.setCharacterEncoding("utf-8"); %>

<html>
<head>
<title>ログイン後</title>
<%
String client_identifier = "aDUvXmXYEFSGtnNgX7v1";
String client_secret = "6w3YoxVpdoZ0mp2Q41IA";
String server_url = "http://localhost:8080/BluemixSSO/index.jsp";

String code = request.getParameter( "code" );
String access_token = null;
String email = "";
if( code != null && code.length() > 0 ){
  //. アクセストークンを取得
  String req_url = "https://idaas.ng.bluemix.net/sps/oauth20sp/oauth20/token?client_id=" + client_identifier + "&client_secret=" + client_secret;
  String param = "grant_type=authorization_code"
      + "&redirect_uri=" + URLEncoder.encode( server_url )
      + "&code=" + code;
  try{
    HttpClient client = new HttpClient();
    PostMethod post = new PostMethod( req_url );
		
    post.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded" );
    post.setRequestHeader( "Content-Length", "" + param.length() );
    post.setRequestBody( param );
		
    int sc = client.executeMethod( post );
    if( sc == 200 ){
      String body = post.getResponseBodyAsString();
      int n1 = body.indexOf( "\"access_token\":\"" );
      if( n1 > 0 ){
        int n2 = body.indexOf( "\"", n1 + 16 );
        if( n2 > n1 ){
          access_token = body.substring( n1 + 16, n2 );
					
          //. アクセストークンを使ってプロファイルデータを取得
          String req_url1 = "https://idaas.ng.bluemix.net/idaas/resources/profile.jsp";
          String param1 = "access_token=" + access_token;

          HttpClient client1 = new HttpClient();
          PostMethod post1 = new PostMethod( req_url1 );
						
          post1.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded" );
          post1.setRequestHeader( "Content-Length", "" + param1.length() );
          post1.setRequestBody( param1 );
          int sc1 = client.executeMethod( post1 );
          if( sc1 == 200 ){
            String body1 = post1.getResponseBodyAsString();
            n1 = body1.indexOf( "\"email\":[\"" );
            if( n1 > 0 ){
              n2 = body1.indexOf( "\"", n1 + 10 );
              if( n2 > n1 ){
                email = body1.substring( n1 + 10, n2 );
              }
            }
          }
        }
      }
    }
  }catch( Exception e ){
    e.printStackTrace();
  }
}else{
	
}
%>
</head>
<body> 
<h1>ようこそ、<%= email %> さん!</h1>
</body>
</html>

index.jsp 内では2回 HTTP リクエストを発行しています。
まず1回目のリクエストでは code パラメータの値を受け取り、その値を指定してアクセストークンを取得しています。
次に2回目のリクエストでは取得したアクセストークンを利用して、ログインユーザーのプロファイルデータにアクセスし、その email アドレスを取り出しています。 ここまでの処理が成功していれば、HTML 部分の <h1> タグ内にそのメールアドレスの値が出力される、というものです。

この辺りの情報について、詳しくは SSO のドキュメントも参考にしてください:
Getting started with Single Sign On (BETA)


実際にこのようなアプリを作って動かしてみると、以下のようになります:

まずログイン前の login.html ページにアクセスします。これは静的なコンテンツなので誰がアクセスしても同じ「ログイン」ボタンだけが表示される画面になるはずです:
2014071408

この「ログイン」ボタンをクリックすると JavaScript が実行されてリダイレクト処理が行われます。その処理の中で IBM ID によるログインが行われます:
2014071409

もし未ログイン状態であれば IBM ID とパスワードを指定していログインしてください:
2014071410

このアプリを最初に使う場合のみ、アクセスコードの入力が求められます。以下の様な画面が表示されると同時に、IBM ID のメールアドレスにメールが送信されます。この例では "4232-" と書かれたテキストフィールドが表示されていますが、送信メールには 4232- で始まる数字4桁-数字6桁 の文字列が書かれているはずです。
2014071411

受け取ったメールの内容の数字6桁部分を書き足して SUBMIT ボタンをクリックします:
2014071412

内容が正しければ先へ進みます。このような処理を毎回繰り返したくない場合はこのブラウザを登録することで回避出来ます。その場合はこの画面で "Register this Device" にチェックを入れ、その下のテキストフィールドにデバイス名を入力(半角スペースは使えません)して「送信」ボタンをクリックします:
2014071413

そして最後に OAuth 認証時にお馴染みに「このアプリに権限を与えるか?」の確認画面が表示されます。チェックボックスにチェックを入れて "Approve" ボタンをクリックします:
2014071414

で、無事に権限の譲渡が行われ、アクセストークンを使ってプロフィールの取得が行われ、(この例では)メールアドレスを取得して画面に表示する、という処理を行うことができました。
2014071415


今回紹介した例はかなりシンプルで、単にログイン前とログイン後のページを分けて、ログイン後のページでログイン情報を表示する、というだけの処理を実装しています。 実際にはログイン前後のページを同じにしたいこともあるでしょうし、またログイン後にログイン情報を残したまま別のページに移動したい、ということもあるでしょう。それらの場合はセッション情報などを使ってステータス管理をしながら処理を記述していくことになると思います。その辺りは IBM Bluemix の SSO サービスに特化した話ではないので、ここでは割愛します。

とはいえ、この例でも分かるようにサードパーティでも IBM Bluemix 上で IBM ID によるログイン管理を行うアプリの開発が出来ることがわかりました。Cloud Foundry をはじめとする各種 PaaS 環境でも共有ユーザーディレクトリが提供されているのは珍しいので便利に使えそうです。

しかも、IBM Bluemix 環境での SSO サービスの利用は(少なくとも 2014/07/14 の時点では)無料だったりします:
2014071401
※IBM Bluemix の各種サービス価格の最新情報はこちらを参照してください:
 IBM Bluemix: Pricing Sheet


どこかのタイミングで有料化される可能性がないとは言えませんが、PaaS 環境で共有で使えるユーザーディレクトリのサービス自体が珍しく、嬉しいです。







このページのトップヘ