Box Node.js SDKとOAuth 2.0の使用

Yuko Taniguchi
Box Developer Japan Blog
16 min readMay 24, 2023

--

クライアント側OAuth 2.0は、Box APIに対してユーザーを認証するための最も簡単な方法の1つです。これは、ユーザーが他のアプリケーションに自分のデータへのアクセスを許可できるようにすることを目的としたオープンスタンダードです。

Boxには、PythonJava.NETiOS、Node.jsなど、さまざまなSDKが用意されています。Box Node.js SDKを使用してシンプルなプロジェクトを作成し、ユーザーがOAuth 2.0を使用して認証できるアプリを作成しましょう。このアプリは、ログインページと、Boxユーザーの基本データを含むメインページで構成し、OAuth 2.0認証に成功した後にアクセスできるようにします。

アプリの作成手順

  1. 📦 Boxアプリを作成する
  2. 📥 プロジェクトを開始して依存関係をインストールする
  3. 📄 ログインページとメインページのテンプレートを作成する
  4. 🔐 Box SDKインスタンスを開始して資格情報を指定する
  5. 🔗 承認URLを取得する
  6. 🏎️💨 Expressアプリを作成する
  7. 🗝️ 承認トークンを取得して永続的クライアントを作成する
  8. 🚀 サーバーを開始する

最終的なプロジェクト: GitHubリポジトリ

前提条件: Node.js無料のBox Individualアカウント*

📦 Boxアプリを作成する

* 無料の開発者アカウントに関わる最近の出来事により、Boxでは、新規の無料開発者アカウントオプションを制限せざるを得なくなりました。

既存のEnterpriseアカウントをお持ちの場合は、手順に従ってサンドボックスを作成してください

それ以外の場合は、無料のBox Individualアカウントを作成してください。クレジットカードは必要ありません。サインアップし、メールアドレスを確認したら、次のリンクにアクセスします: https://app.box.com/developers/console

Boxは、数週間前に新しいアプリ作成プロセスをリリースしたため、簡単にそのプロセスを説明します。開発者コンソールで [アプリの新規作成] をクリックし、[カスタムアプリ] を選択します。

Box開発者コンソール: 新しいカスタムアプリの作成

新しい作成プロセスでは、アプリ名、簡単な説明、アプリの提案 (この場合はカスタムポータル) など、いくつかの追加情報を入力するように求められます。後に続く選択要素では、Boxをご利用のお客様の場合は [お客様]、組織外で使用するアプリケーションを作成する場合は [パートナー] を選択します。

最後の手順では、[ユーザー認証 (OAuth 2.0)] を選択し、アプリを作成します。[構成] タブで、OAuth 2.0資格情報であるクライアントIDとクライアントシークレットを確認します。これらの値は後で必要になります。

リダイレクトURIとCORSドメイン

リダイレクトURIをhttp://localhost:8000/authorize_callbackと定義します。OAuth 2.0を使用してアプリで認証されたユーザーは、一時的なコードパラメータを使用してこのルートにリダイレクトされます。詳細については、後の手順で説明します。

Box開発コンソール: [OAuth 2.0 リダイレクトURI] の設定

最後に、CORSドメインを定義する必要があります。差し当たり、http://localhost:8000を追加します。

Box開発コンソール: [CORSドメイン] の設定

デフォルトのBoxアプリケーションスコープは、[Boxに格納されているすべてのファイルとフォルダの読み取り] です現時点ではこの設定で十分ですが、より高度な機能をカスタムアプリに追加する場合は、[Boxに格納されているすべてのファイルとフォルダへの書き込み] チェックボックスをオンにする必要があります。

📥 プロジェクトを開始して依存関係をインストールする

ターミナルを開いて新しいフォルダを作成し、新しいプロジェクトを開始します。

mkdir name-of-node-app
cd name-of-node-app
git init

ごくシンプルなプロジェクトのままにし、基本的な依存関係をインストールします。

  • Dotenvを使用すると、.envファイルから変数を読み取って埋め込むことができます。
npm install dotenv --save
  • ExpressはNode.jsのフレームワークです。
npm install express --sav
  • express-sessionは、セッションミドルウェアを作成するためのモジュールです。express-sessionはリリース可能なアプリにとって最適なソリューションではないことに留意してください。そのため、Redisなど、別のより安全なメモリストレージの実装を使用することをお勧めします。
npm install express-session --save
npm install hbs --save
npm install --save box-node-sdk

package.jsonファイルの依存関係を以下に示します。

{
"dependencies": {
"dotenv": "^16.0.3",
"express": "^4.18.2",
"express-session": "^1.17.3",
"hbs": "^4.2.0"
"box-node-sdk": "^2.8.1",
}
}

index.jsファイルを作成し、これらのモジュールをインポートします。組み込みのpathモジュールは、hbsテンプレートファイルにアクセスするのに役立ちます。

require('dotenv').config();
const express = require('express');
const session = require('express-session');
const path = require('path');
const BoxSDK = require('box-node-sdk');

envファイル

.envファイルも作成します。これは、3組のキーと値のペアで構成されます。クライアントIDとクライアントシークレットは、前の手順でアクセスした、Box開発者コンソールの [構成] タブにあります。セッションシークレットは、セッションのハッシュ値を計算し、自分で強力なハッシュ (この例では、ランダム化された長い文字列になります) を生成するために使用されます。

CLIENT_ID='BoxAppClientID'
CLIENT_SECRET='BoxAppClientSecret'
SESSION_SECRET='SessionSecrerKey'

.gitignoreファイルを追加し、node modulesフォルダと.envファイルを含めます。

📄 ログインページとメインページのテンプレートを作成する

プロジェクトのhandlebarsテンプレートを格納するフォルダを作成します。まず、デフォルトのlayout.hbsファイルが必要です。少し見た目をよくするために✨、Bootstrap 5へのCDNリンクを含めましたが、これは省略してもまったく問題ありません。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Box node.js SDK and OAuth sample app</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
</head>

<body>
{{{body}}}
</body>
</html>

ログインページには、生成されたログインリンクが含まれており、このリンクからOAuth 2.0の認証プロセスにリダイレクトされます。このリンクをlogin_urlパラメータとして定義します。このリンクは、後でBox SDKを使用して生成し、テンプレートに渡します。

<main class="container">
<h1>Log in to Box Node SDK with OAuth sample app</h1>
<a class="btn btn-primary" href={{login_url}}>Login</a>
</main>

アプリのメイン画面には、BoxユーザーID、Box Node.js SDKを使って動的に取り込んだBoxユーザー名、ログアウトリンクが含まれます。

<main class="container">
<section>
<h1>Your account</h1>
<h2>Box user name: </h2>
{{ name }}
<h2>Box User id: </h2>
{{ id }}
<section>
<section>
<a class="btn btn-primary" href="/logout">Logout</a>
</section>
</main>

フォルダ構造には、画像を提供するstaticフォルダも含めます。現在、プロジェクトの構造は次のようになっています。

プロジェクトのフォルダ構造

🔐 Box SDKインスタンスを開始して資格情報を指定する

index.jsファイルで、.envファイルの変数を指定して、Box Node.js SDKを開始します。

const sdk = new BoxSDK({
clientID: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET
});

🔗 承認URLを取得する

前述のとおり、ユーザーをOAuth 2.0承認プロセスにリダイレクトするためのログインURLが必要です。index.jsファイルでこのURLを生成します。また、ここでポートも定義し、Boxの構成設定で渡されるものと一致していることを確認します。

const PORT = process.env.PORT || 8000;

const authURL = sdk.getAuthorizeURL({
response_type: 'code',
redirect_uri: `http://localhost:${PORT}/authorize_callback`
});

🏎️💨 Expressアプリを作成する

ここからは楽しい内容になります。Expressアプリを作成して、ユーザーセッションを作成し、ログインページとアプリのメイン画面のロジックを定義する必要があります。

const app = express();

app.use(
// For production ready apps use other more secure memory storage implementation like Redis
session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: true,
// Secure will set cookies only on https but we in localhost here
// cookie: { secure: true }
})
);
// Optional - for static images and files loading
app.use(express.static(__dirname + '/static'));

// Use the hbs engine and pass the views folder
app.set('view engine', 'hbs');
app.set('views', path.join(__dirname, 'views'));

ログインページについては、前の手順で作成したauthURLを渡し、ログインテンプレートをレンダリングします。

app.get('/login', (req, res) => {
res.render('login', { login_url: authURL });
});
アプリのログインページ

アプリのメインページは、ログインに成功した後にのみ使用できるようになります。これを実現するために、ユーザーのセッションがアクティブかどうかを確認するミドルウェアが必要です。アクティブでない場合はログインページにリダイレクトされます。

const auth_middleware = (req, res, next) => {
if (req.session.user) return next();

res.redirect('/login');
};

auth_middlewareをパラメータとしてメインページのハンドラに渡します。メインのindex.hbsテンプレートをレンダリングし、ユーザーの詳細情報を渡します。

app.get('/', auth_middleware, (req, res) => {
const user = req.session.user;

res.render('index', {
name: user.name,
id: user.id
})
});

🗝️ 承認トークンを取得して永続的クライアントを作成する

承認コールバックを処理します。一時的なコードをキャッチし、それが存在する場合はトークンと永続的クライアントを作成します。ユーザーの詳細情報を取得し、セッションに保存します。その処理が成功すると、ユーザーはアプリのメインページにリダイレクトされます。ユーザーがアクセスの許可を拒否した場合は、「Access denied (アクセスが拒否されました)」というメッセージが表示されます

app.get('/authorize_callback', async (req, res) => {
// Get the temporaty code
const { code } = req.query;

if (!code) return res.status(401).send("Access denied");
const tokenInfo = await sdk.getTokensAuthorizationCodeGrant(code);
const client = sdk.getPersistentClient(tokenInfo);
// Get user details
const user = await client.users.get(client.CURRENT_USER_ID);

// Save user in session for persistence, this is basic of auth middleware implementation
req.session.user = user;
// Split storing access token and refresh token for production
req.session.user_token = tokenInfo;

res.redirect('/');
});

サーバーを稼働させたら、ログインリンクをクリックしてください。承認ページにリダイレクトされます。

承認ページ
[Boxへのアクセスの許可] 画面

さらに、ログアウトリンクのロジックを追加し、ユーザーセッションを破棄します。

app.get('/logout', (req, res) => {
req.session.destroy();
res.redirect('/login');
})

最後に、Page not found! (ページが見つかりません) というメッセージが表示される404ページを作成します。

app.use('*', (req, res) => {
res.setHeader('Content-type', 'text/html')
res.status(404).header().end('<h1>Page not found!</h1>');
})

🚀 サーバーを開始する

そして、サーバーを開始します。

app.listen(PORT, () => {
console.log(`Listening to requests on port http://localhost:${PORT}`);
});

ターミナルで次のように入力すると、アプリケーションを実行できます。

node index.js

また、package.jsonファイルでstartスクリプトを定義することもできます。Boxの資格情報を使用してログインし、Boxへのアクセスを許可したら、アカウントページにリダイレクトされます。

ログインの成功後に表示されるアカウントページ

これで、Box Node.js SDKを使用してアプリを次の段階に進めることができます。🎉

詳細情報:

TwitterでBox Developersプロフィールをフォローすると、最新情報を入手できます。

--

--