【OPTiM Cloud IoT OS API利用編】OPTiM Cloud IoT OSのアカウントを使ったOAuth連携の実装

こんにちは。プラットフォーム技術戦略室の青木です。

最近でなくとも、TwitterやGoogle,FacebookなどのOAuth 2.0によるAPI利用が出来るWebアプリケーションが増えつつあります。APIを利用する際に安全に連携することが出来ます。

さて、今回はOAuth 2.0によるAPI利用が可能な自社サービスの「OPTiM Cloud IoT OS」で実際にOAuthでOPTiM Cloud IoT OSのAPIを利用出来るようにします。

www.optim.cloud

前置き

早くOAuth 2.0によるAPI実行を実装してみたいという方は、2. OAuth Clientを作成するまで飛ばして構いません

この記事で出来るようになること

  • OAuth 2.0を利用し、APIを叩くことが出来る

1. OAuth 2.0を簡単に実装出来る基盤を作る

https://cdn-ak.f.st-hatena.com/images/fotolife/o/optim-tech/20210129/20210129193537.png

「OPTiM Cloud IoT OS」のOAuth 2.0

自社サービスである「OPTiM Cloud IoT OS」では、OAuth 2.0が備わっています。OAuth 2.0を利用することでAPIへ安全にアクセスすることが可能になります。

以下は、「OPTiM Cloud IoT OS」のドキュメントに記載されている内容です。

本サービスのAPIは、OAuth 2.0*1によって保護されています。 そのため、本サービスのAPIを利用してリソースへアクセスする際は、OAuth 2.0の認可の仕組みを利用する必要があります。

OAuth 2.0は、アプリケーションによるリソースアクセスの権限を認可するためのスタンダードなフレームワークです。 本サービスでは、OAuth 2.0のフローとして、以下のフローをサポートしています。

  • Authorization Code Grant
  • Client Credentials Grant

また、本サービスを使ったログイン(フェデレーション、シングルサインオン)を行うアプリケーションを作成する場合は、OpenID Connect*2を利用します。 OpenID Connectは、OAuth 2.0をベースとしたID連携(フェデレーション)の標準プロトコルです。 そのため、OAuth 2.0によるAPI認可と合わせてユーザー認証を行うことができるようなっています。

今回はOpenIDConnectは利用せず、OAuth 2.0というフレームワークを利用します。

OAuth 2.0を使ったアプリケーションの例

OAuth 2.0 は認可のためのフレームワークです。以下のようなユースケースにおいて、安全にAPIへのアクセスを実現することが出来ます。

  • Twitterクライアントのように、APIによりリソースを閲覧、操作するだけのアプリケーション
  • アプリケーション本体に独自のDBやユーザ情報を持っている場合、ユーザ情報をインポートする為にAPIを利用する場合(独自のユーザ情報と紐付けを行うのではなくあくまでインポートを行う為)
  • 自身のアプリケーションでAPIを利用したい場合
    • Twitterでつぶやく、タイムラインを取得するなど

ユーザ情報と連携する場合は今回は利用しない OpenID Connect を利用してください。

Passport.js でかんたんに導入出来るOAuth 2.0

www.passportjs.org

Passport.jsでOAuth 2.0を利用するために使える Strategy(ex:Facebook Strategy)というものがあります。

上記リンクではFacebookのものを記述しましたが、他にも様々なOAuth 2.0がStrategyによって簡単に実装出来ます。

http://www.passportjs.org/packages/

OPTiM Cloud IoT OS の Strategy を作ってみた

github.com

他のStrategyを参考に、自社サービスのStrategyを作ってみました。

サンプルコードではNode.jsの軽量WebフレームワークでおなじみのExpressを利用したものを記述してあります。

The MIT License | Copyright (c) 2021 OPTiM Corporation https://www.optim.co.jp/

こちらは、OPTiM公式OSS*3として公開されています。

2. OAuth Clientを作成する

OPTiM Cloud IoT OS に作成するアプリケーションの登録をすると、OAuth Clientが作成されて認証・認可を行う準備が可能になります。 画像のように、アプリケーションの登録を行い、下準備を行います。

OPTiM Cloud IoT OS に3ヶ月無償トライアルにて*4を行うと、アプリケーション登録を行える Developer Center にアクセスすることが出来ます。

https://cdn-ak.f.st-hatena.com/images/fotolife/o/optim-tech/20210127/20210127114448.png

項目 設定情報 解説
表示名 tech_blog_sample_passport 認可画面に表示されるアプリケーション名
状態 有効 このアプリケーションが有効かどうか
種別 Webアプリケーション 他に、ネイティブアプリやデバイスなどが存在する
リダイレクトURIs http://localhost:3000/oauth2/callback 認可レスポンスを送信するURI。セキュリティを強化するために記載し、Webアプリケーションに設定されたURIと同じでなければならない
APIスコープ openid, profile このアプリケーションがユーザのデータにアクセスする権限を選択。認可画面にスコープに応じた同意画面が表示される
クライアントID 非公開 認証・認可フローに利用するID
クライアントシークレット 非公開 認証・認可フローに利用するシークレット
リソースオーナー アカウント名 このOAuthClientの持ち主

上記のような登録作業は、TwitterFacebookでも同じように行います。PassportではTwitter,FacebookがStrategyとしてサポートされています。今回実装する内容と同じようなフローでTwitter,FacebookへのAPIアクセスが可能になります。

さて、登録した情報を利用し、OAuth 2.0によってAPIを叩いていきます。

3. OAuth 2.0で認可し、APIを叩いてみる

github.com

基本的には、リポジトリに記載されているサンプルコードに則って実装すればスムーズに出来ます。 ここでは実際にサンプルコードを実装した場合どのような挙動になるのかも踏まえて紹介いたします。

3-1. Expressの基盤を作る

Express Generatorでアプリケーションを生成します。

とりあえずHello Worldを表示するまで、チュートリアルを進めましょう。

express myapp
cd myapp
yarn
yarn start

https://cdn-ak.f.st-hatena.com/images/fotolife/o/optim-tech/20210127/20210127114451.png

3-2. OPTiM Cloud IoT OS でログインの実装

Usageに記述してあるサンプルを参考に、コードを組み立てていきます。

必要なパッケージをインストール

yarn add passport express-session @optim-corp/passport-cios

passportの設定を記述

app.jsに記述します

const passport = require("passport")
const session = require("express-session")
const CIOSStrategy = require("@optim-corp/passport-cios")

app.use(session({
  secret: 'secret', // TODO: 任意のSecret文字列
  resave: true,
  saveUninitialized: true
}))

//=====

passport.use(new CIOSStrategy({
        clientID: "", // TODO: ここにClientIDを入力
        clientSecret: "", // TODO: ここにClientSecretを入力
        callbackURL: "http://localhost:3000/oauth2/callback",
        scope: "openid profile user.profile", 
      },
    (accessToken, refreshToken, res, profile, cb) => {
        return cb(null, res)
    }
))
passport.serializeUser(function(user, done) { done(null, user); });
passport.deserializeUser(function(user, done) { done(null, user); });

app.use(passport.initialize())
app.use(passport.session());

アクセストークンを取得し、セッションに格納する

app.jsに記述します

app.get("/login/cios", passport.authenticate("cios"))
app.get("/oauth2/callback", passport.authenticate("cios", { failureRedirect: "/" }), (req, res) => {
    req.session.access_token = req.user.access_token    // AccessToken
    req.session.refresh_token = req.user.refresh_token  // Refresh Token
    return res.redirect("/")    // Redirect
},)
app.get("/logout", (req, res)=>{
    req.session.access_token = null    // AccessToken
    req.session.refresh_token = null  // Refresh Token
    return res.redirect("/")    // Redirect
})

アクセストークンを利用し、プロフィールを取得するAPIを叩いてみる

OPTiM Cloud IoT OS の Account APIでは /v2/me というPathで自らのプロフィールを取得することができます。

app.jsに記述します

簡単に実行するため、node-fetch を利用しています。また、エラーハンドリング等も行っていませんので、プロダクトに入れ込む際は注意してください。

const fetch = require('node-fetch')

// ...省略

app.get('/me', async (req,res)=>{

  // OAuth認可を一度も受けていない場合エラーを返す
  if (!req.session.access_token) {
    console.error("not login");
    const error = {
      "error": "not login"
    }
    return res.status(401).json(error)
  }

  // "/me"を叩く
  const response = await fetch('https://accounts.optimcloudapis.com/v2/me',{
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer '+ req.session.access_token
    }
  })
  return res.json(await response.json())
})

確認のため、/me情報を表示する

Viewに表示するため、views/index.jadeに追記します。

今回はセッションを用いていますので、Javascriptでフロントからfetchを叩くと取得したAccessTokenを利用して/meにアクセスします。

block content
  h1= title
  p Welcome to #{title}
+ p#me "/me"
+ script.
+   fetch("/me")
+   .then(res=>res.json())
+   .then(me => {
+     console.log(me)
+     document.getElementById("me").innerHTML = JSON.stringify(me)
+   })

編集後はサーバを再起動してください。

3-3. 動作確認

http://localhost:3000/login/cios へアクセスすると、OPTiM Cloud IoT OS のログイン画面が表示されます。

https://cdn-ak.f.st-hatena.com/images/fotolife/o/optim-tech/20210127/20210127114427.png

ログインすると続いて認可画面が表示されます。これは、先程設定した Scope の利用を、ユーザーに同意してもらうための画面です。

https://cdn-ak.f.st-hatena.com/images/fotolife/o/optim-tech/20210127/20210127114431.png

認可を行うと、/へリダイレクトされ、トップページに/meの情報が表示されます。

https://cdn-ak.f.st-hatena.com/images/fotolife/o/optim-tech/20210129/20210129194801.png

さいごに

今回は passport-cios で OAuth 2.0 を利用して、OPTiM Cloud IoT OS の API を簡単に実行してみました。 OPTiM Cloud IoT OS は他にも、OAuth 2.0 を認証用途に拡張した OpenID Connect による認証連携もサポートしています。 そのため、OAuth 2.0 が実装できていると、少しの追加対応で認証連携も実装できるようになります。

OAuth 2.0は非常に便利な機能ですので、この文化を広めてより楽に開発が出来るようにしたいですね。


オプティムではOPTiM Cloud IoT OSの開発、及び利用するアプリケーション開発を行うエンジニアを募集しています。

www.optim.co.jp