目標
Node-RED で App ID を使ったサインイン処理フローを学ぶ
知識材料
参考ページ
今回のゴール
IBM Cloud App ID のAPIを使って OAuth
のフローを体験する
実践
IBM Cloud 設定
App ID リソース作成
カタログから選択
IBM Cloud にログインして、画面上部の 「カタログメニュ」 をクリック後、検索欄に app
と入力する。
検索欄の下部に 「App ID」 がサジェスト表示されるのでクリックして選択する。
App IDサービスの基本設定
「ロケーションの選択」 を 東京(jp-tok)
に設定する。
画面右のサマリー下部の利用規約に同意して、「作成ボタン」 をクリックする。
App ID テストユーザ作成
作成された [App ID リソース] の設定画面が表示されるので、画面左側のメニューから 「クラウドディレクトリ」 -> 「ユーザー」 を選択する。
画面下部の 「Create User ボタン」 をクリックする。
[Add a user to test your application ダイアログ] が表示されるので、Email:
、Password:
、Re-enter Password:
の必須項目を入力して、画面下部の 「Saveボタン」 をクリックする。
App ID アプリケーション設定
画面左側のメニューから **「アプリケーション」**を選択する。
アプリケーション一覧が表示されるので画面右側の 「Add Applicationボタン」 をクリックする。
[Add Application ダイアログ] が表示されるので、「Name」 に任意の適切な文字列を入力し 「Saveボタン」 をクリックする。
作成されたアプリケーションが一覧に表示されるのでクリックして詳細を開き、下記項目の値をメモ しておく。
- clientId
- tenantId
- secret
- profilesUrl
認証処理の設定
画面左側のメニューから **「認証の管理」**を選択する。
[Manage identiry providers] が表示されるので画面上部の 「Authentication settingsタブ」 をクリックする。
Add web redirect URLs 欄に、{利用を想定しているNode-REDのドメイン:ポート番号}/auth_redirect
を入力し、テキスト入力欄右の (+)ボタン をクリックする。
Node-RED フロー作成
フロー作成
下記フローをコピーして Node-RED にインポートする。
[{"id":"d76271fd72263d3e","type":"tab","label":"IBM-App-id","disabled":false,"info":"","env":[]},{"id":"1565dfe77fe1efe6","type":"comment","z":"d76271fd72263d3e","name":"open-id-configuration","info":"","x":120,"y":80,"wires":[]},{"id":"96b4611f24117caa","type":"inject","z":"d76271fd72263d3e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":120,"y":120,"wires":[["d395d7be7c4c3039"]]},{"id":"e5ab70743b6389b6","type":"http request","z":"d76271fd72263d3e","name":"","method":"use","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":490,"y":120,"wires":[["9dadc3a98ca6d324"]]},{"id":"9dadc3a98ca6d324","type":"debug","z":"d76271fd72263d3e","name":"debug 2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":660,"y":120,"wires":[]},{"id":"d395d7be7c4c3039","type":"function","z":"d76271fd72263d3e","name":"function 1","func":"const END_POINT = env.get(\"profilesUrl\");\nconst TENANT_ID = env.get(\"tenantId\");\n\nmsg.url = `${END_POINT}/oauth/v4/${TENANT_ID}/` \n + \".well-known/openid-configuration\";\nmsg.method = \"GET\";\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":300,"y":120,"wires":[["e5ab70743b6389b6"]]},{"id":"ad89d8a208dc7564","type":"comment","z":"d76271fd72263d3e","name":"authorization","info":"","x":90,"y":200,"wires":[]},{"id":"65a9fff4e36ab576","type":"function","z":"d76271fd72263d3e","name":"RedirectLocation","func":"const END_POINT = env.get(\"profilesUrl\");\nconst TENANT_ID = env.get(\"tenantId\");\nconst CLIENT_ID = env.get(\"clientId\");\n\nconst REDIRECT_URL = env.get(\"redirectUrl\");\n\nconst SCOPE = \"openid\";\n\nmsg.url = `${END_POINT}/oauth/v4/${TENANT_ID}/` \n + \"authorization\"\n + \"?\" \n + \"response_type=code\"\n + `&client_id=${CLIENT_ID}`\n + `&redirect_uri=${REDIRECT_URL}`\n + `&scope=${SCOPE}`;\n\nmsg.headers = {\n location : msg.url,\n};\nmsg.statusCode = 301;\nmsg.method = \"GET\";\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":330,"y":240,"wires":[["c05753e6f41dbfb8","11041e2ee2cb90ee"]]},{"id":"3023d7685bd5ed79","type":"http in","z":"d76271fd72263d3e","name":"","url":"auth_redirect","method":"get","upload":false,"swaggerDoc":"","x":130,"y":300,"wires":[["1ccd5e34f70e9132","11041e2ee2cb90ee"]]},{"id":"11041e2ee2cb90ee","type":"debug","z":"d76271fd72263d3e","name":"debug 4","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":760,"y":300,"wires":[]},{"id":"12d86ab2ae241fcd","type":"http in","z":"d76271fd72263d3e","name":"","url":"/login","method":"get","upload":false,"swaggerDoc":"","x":100,"y":240,"wires":[["65a9fff4e36ab576"]]},{"id":"c05753e6f41dbfb8","type":"http response","z":"d76271fd72263d3e","name":"","statusCode":"","headers":{},"x":650,"y":240,"wires":[]},{"id":"67d3390410bb5b01","type":"http response","z":"d76271fd72263d3e","name":"","statusCode":"","headers":{},"x":750,"y":540,"wires":[]},{"id":"1ccd5e34f70e9132","type":"function","z":"d76271fd72263d3e","name":"GetToken","func":"const END_POINT = env.get(\"profilesUrl\");\nconst TENANT_ID = env.get(\"tenantId\");\nconst CLIENT_ID = env.get(\"clientId\");\nconst SECRET = env.get(\"secret\");\n\nconst REDIRECT_URL = env.get(\"redirectUrl\");\n\nconst bearer_base64 = Buffer.from(`${CLIENT_ID}:${SECRET}`).toString(\"Base64\");\n\nmsg.url = `${END_POINT}/oauth/v4/${TENANT_ID}/` \n + \"token\";\nmsg.method = \"POST\";\nmsg.headers = {\n \"Authorization\": `Basic ${bearer_base64}`,\n \"content-type\" : \"application/x-www-form-urlencoded\"\n};\nmsg.payload = {\n \"grant_type\": \"authorization_code\",\n \"redirect_uri\" : REDIRECT_URL,\n \"code\" : msg.payload.code\n}\n\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":320,"y":360,"wires":[["2769f444b5411e1b"]]},{"id":"2769f444b5411e1b","type":"http request","z":"d76271fd72263d3e","name":"","method":"use","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":490,"y":360,"wires":[["11041e2ee2cb90ee","3049657267a438da"]]},{"id":"6520a4f9a806cb4b","type":"function","z":"d76271fd72263d3e","name":"decode JWT","func":"var decode_strings = \"\";\nmsg.payload.access_token.split('.').forEach(function(element) {\n decode_strings += Buffer.from(element, 'base64').toString() + \",\";\n});\n\n\nmsg.payload = decode_strings; //decodeBase64( msg.payload.access_token.split('.')[2]);\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":570,"y":460,"wires":[["3049657267a438da"]]},{"id":"4fc79d9e499585dc","type":"http request","z":"d76271fd72263d3e","name":"","method":"use","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":510,"y":540,"wires":[["67d3390410bb5b01"]]},{"id":"3049657267a438da","type":"function","z":"d76271fd72263d3e","name":"getUserInfo","func":"const END_POINT = env.get(\"profilesUrl\");\nconst TENANT_ID = env.get(\"tenantId\");\n\nmsg.url = `${END_POINT}/oauth/v4/${TENANT_ID}/` \n + \"userinfo\";\nmsg.method = \"GET\";\nmsg.headers = {\n \"Authorization\": `Bearer ${msg.payload.access_token}`,\n};\n\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":330,"y":540,"wires":[["4fc79d9e499585dc"]]}]
環境変数の設定
前述の工程でメモした値を Node-RED の環境変数に設定する。
Node-RED 画面右上のメニューから **「設定」**をクリックする。
下記の環境変数を追加する
- clientId
- tenantId
- secret
- profilesUrl
-
ここで入力したURL
実行と結果
以下のURLにアクセスする。
{利用を想定しているNode-REDのドメイン:ポート番号}/login
ログイン画面が表示されるので「App ID テストユーザ作成」で作成したユーザの Email:
、Password:
を入力して 「Sign inボタン」 をクリックする。
サインインに成功すると、ブラウザに「App ID テストユーザ作成」で作成したユーザ情報が JSON 形式で表示される。