Edited at
IBM CloudDay 16

Auth0 の Node.js サンプルプログラムを IBM Cloud にデプロイする

More than 1 year has passed since last update.

本エントリーは IBM Cloud Advent Calendar 2017 16日目のエントリーです。

16日目の今日は、少し趣向を変えて認証基盤サービス (IdMaaS) である Auth0 の紹介と、サンプルアプリを IBM Cloud へデプロイしてみたいと思います。よろしくお願いいたします。


本エントリーの対象

認証基盤サービス (IdMaaS) である Auth0 を知らない人、クロスプラットフォームで簡単に認証認可周りを実装したい人向けのエントリーになります。

このサービスを先日 Security-JAWS の勉強会に行った際、初めて知り感動しました。

今まで使っていた Safari Books OnlineLinux AcademyA Cloud Guru などで使われているということで、よく見てみるとたしかにログイン時の URL に auth0.com がついています。これらのサービスは、Webとモバイルアプリを出していて、こういうサービスでは Auth0 のありがたさをより実感できそうです。


本エントリーを読んでできるようになること

Auth0 のすばらしさに感動する


本エントリーの執筆時の実行環境

$ sw_vers

ProductName: Mac OS X
ProductVersion: 10.13.1
BuildVersion: 17B1002

$ npm -v
5.2.0

$ node -v
v6.11.1


Auth0 とは

Auth0 のセールスエンジニアの方が SlideShare にスライドを上げているので、これが一番わかりやすいです。

Auth0でAWSの認証認可を強化 (SlideShare)

Auth0 は認証基盤サービス (IdMaaS) をやっている会社の名前でありサービスの名前です。既にいろいろなサービスで使用されており、パブリッククラウドの1サービスである SSO サービスを使用するよりも安心感があり品質も高いです。また、アプリが IBM Cloud や AWS、iOS からアクセスされるようなものであってもプラットフォームを跨いだ認証認可機能を構築できます。

認証認可周りは、開発すると全体の開発工数の 30% くらいになるそうです。

スライド内のアンケートでは Auth0 を使うと 94% の企業が1ヶ月以内に Auth0 を実装できたと言っています。

Cognito 使うと、Webとアプリ両方の実装に時間がかかるらしいです。

Auth0 社は認証だけでなく、Webtaskというサーバーレスコンピューティング環境も提供しているそうです

http://martinfowler.com/articles/serverless.html

結構な Open Source プロジェクトがあります。

全部見れてないですが、Open Source になっているのは SDK とかでしょうか。いろんなプラットフォームで実装しやすいように整えられている感じがあります。Xamarin 向けとかもあります。

https://auth0.com/opensource


サンプルプログラムをローカルで動かす


Auth0 に登録する

ポチポチ登録していきます

SIGN UP

今回は GitHub アカウントで登録しました。

22 日間フル機能利用可能。それ以降は Free ライセンスとして継続利用かのうとのこと。

テナントドメインはログイン時のURLになり変更不可なので慎重に。

リージョンを選択します。確か、Auth0 は AWS 上と、一部 Heroku 上で動いていると聞いた気がします。

+ NEW CLIENT

適当な名前を付けて、今回は Node.js なので、Single Page Web Applications を選択。

API キー的なのが表示されるので、これらを後で使用します。

この Settings タブを下の方にスクロールしていくと Allowed Callback URLs という欄があります。ハンズオンではここに Callback URL をセットします。


Node.js のサンプルプログラムをダウンロードする

Node.js のサンプルプログラムの公式の紹介ページはこちら

ここに書いてある説明通り、GitHub のリポジトリ auth0-samples/auth0-nodejs-webapp-sample から Clone してきます。

git clone https://github.com/auth0-samples/auth0-nodejs-webapp-sample.git

cd auth0-nodejs-webapp-sample/01-Login


設定ファイルなどを見てみる


package.json

{

"name": "auth0-nodejs-regular-webapp-sample",
"version": "1.0.0",
"description": "Auth0 + NodeJS Regular WebApp seed",
"repository": "git://github.com/auth0/node-auth0",
"author": "Auth0",
"license": "MIT",
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"body-parser": "^1.16.1",
"connect-ensure-login": "^0.1.1",
"connect-flash": "^0.1.1",
"cookie-parser": "^1.4.3",
"debug": "^2.6.1",
"dotenv": "^4.0.0",
"express": "^4.16.1",
"express-session": "^1.11.3",
"morgan": "^1.8.1",
"passport": "^0.3.0",
"passport-auth0": "^0.6.0",
"pug": "~2.0.0-beta11",
"serve-favicon": "^2.4.0"
}
}

npm start を入力したときには node ./bin/www が実行されるみたいです。


www

#!/usr/bin/env node

/**
* Module dependencies.
*/

var app = require('../app');
var debug = require('debug')('nodejs-regular-webapp2:server');
var http = require('http');

/**
* Get port from environment and store in Express.
*/

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

/**
* Create HTTP server.
*/

var server = http.createServer(app);

/**
* Listen on provided port, on all network interfaces.
*/

server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

/**
* Normalize a port into a number, string, or false.
*/

function normalizePort(val) {
var port = parseInt(val, 10);

if (isNaN(port)) {
// named pipe
return val;
}

if (port >= 0) {
// port number
return port;
}

return false;
}

/**
* Event listener for HTTP server "error" event.
*/

function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}

var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;

// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}

/**
* Event listener for HTTP server "listening" event.
*/

function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
console.log('Listening on ' + bind);
}


#!/usr/bin/env node とは (Stack Overflow)


.env.example

AUTH0_CLIENT_ID={CLIENT_ID}

AUTH0_DOMAIN={DOMAIN}
AUTH0_CLIENT_SECRET={CLIENT_SECRET}

後で .env.example このファイルをコピーして、Auth0 でクライアントを作成したときの CLIENT_ID などを入力していきます。

以下は、サンプルを Docker で動かすためのファイルで、今回は使用しません。

- .dockerignore

- Dockerfile

- exec.ps1

- exec.sh


サンプルプログラムの実行

まず Auth0 のサイトで Callback URL に http://localhost:3000/callback を設定します

package のインストール

# package.json に書いてある passport, passport-auth0, connect-ensure-login のバージョンを最新にする

npm install passport passport-auth0 connect-ensure-login --save
# package.json に書いてある package をインストール
npm install

CLIENT_ID などの設定

cp .env.example .env

vim .env

dotenv package がインストールされているので、.env に書いた内容をプラグラム内から環境変数として取得できます。


.env

AUTH0_CLIENT_ID=xxxxxx.auth0.com

AUTH0_DOMAIN=aAbBcCdD
AUTH0_CLIENT_SECRET=eEfFgGhH

起動

npm start

ブラウザで http://localhost:3000 にアクセスすると、Auth0 を使用してログインできます。


サンプルプログラムを IBM Cloud 上で動かす

先程のサンプルプログラムを Bluemix IBM Cloud にデプロイします。


IBM Cloud で Node.js アプリをデプロイする

カタログから選んでデプロイするだけなので、割愛します。


Callback URL の設定

Callback URL を https://<YourApp>.mybluemix.net/callback に変更します

.envAUTH0_CALLBACK_URL を追加します


.env

AUTH0_CLIENT_ID=xxxxxx.auth0.com

AUTH0_DOMAIN=aAbBcCdD
AUTH0_CLIENT_SECRET=eEfFgGhH
AUTH0_CALLBACK_URL=https://<YourApp>.mybluemix.net/callback

ちなみに、app.js を見ると Callback URL 取得部分は以下のようになっています。AUTH0_CALLBACK_URL を設定していない時は localhost:3000 になります。


app.js(一部抜粋)

  {

domain: process.env.AUTH0_DOMAIN,
clientID: process.env.AUTH0_CLIENT_ID,
clientSecret: process.env.AUTH0_CLIENT_SECRET,
callbackURL:
process.env.AUTH0_CALLBACK_URL || 'http://localhost:3000/callback'
},

IBM Cloud へデプロイするため manifest.yml を作成します。


manifest.yml

applications:

- name: <your-app-name>
random-route: true
memory: 128M

デプロイして動作確認します。

cf ではなく bx コマンドを使いましょう。

bx login

bx app push


終わりに

認証認可周りはかなりコアな部分なので、IBM Cloud のサービスを使用して実装するのは少し心配な気がします。Auth0 を使用しておけば気持ちが楽になります。

本エントリーでは Node.js のチュートリアルを動かしただけですが、ネイティブアプリと Web アプリ両方で動かすのとかも面白そうです。

Kotlin + Spring Boot + Auth0 とか楽しそう。

Developing RESTful APIs with Kotlin (Auth0 の developers blog)

developers blog のコード公開用の auth0-blog という Organization もあって良さがある。