こんにちは。プラットフォーム技術戦略室の青木です。
最近でなくとも、TwitterやGoogle,FacebookなどのOAuth 2.0によるAPI利用が出来るWebアプリケーションが増えつつあります。APIを利用する際に安全に連携することが出来ます。
さて、今回はOAuth 2.0によるAPI利用が可能な自社サービスの「OPTiM Cloud IoT OS」で実際にOAuthでOPTiM Cloud IoT OSのAPIを利用出来るようにします。
前置き
早くOAuth 2.0によるAPI実行を実装してみたいという方は、2. OAuth Clientを作成するまで飛ばして構いません
この記事で出来るようになること
- OAuth 2.0を利用し、APIを叩くことが出来る
1. OAuth 2.0を簡単に実装出来る基盤を作る
「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
Passport.jsでOAuth 2.0を利用するために使える Strategy(ex:Facebook Strategy)というものがあります。
上記リンクではFacebookのものを記述しましたが、他にも様々なOAuth 2.0がStrategyによって簡単に実装出来ます。
http://www.passportjs.org/packages/
OPTiM Cloud IoT OS の Strategy を作ってみた
他の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
にアクセスすることが出来ます。
項目 | 設定情報 | 解説 |
---|---|---|
表示名 | tech_blog_sample_passport |
認可画面に表示されるアプリケーション名 |
状態 | 有効 | このアプリケーションが有効かどうか |
種別 | Webアプリケーション | 他に、ネイティブアプリやデバイスなどが存在する |
リダイレクトURIs | http://localhost:3000/oauth2/callback |
認可レスポンスを送信するURI。セキュリティを強化するために記載し、Webアプリケーションに設定されたURIと同じでなければならない |
APIスコープ | openid , profile |
このアプリケーションがユーザのデータにアクセスする権限を選択。認可画面にスコープに応じた同意画面が表示される |
クライアントID | 非公開 | 認証・認可フローに利用するID |
クライアントシークレット | 非公開 | 認証・認可フローに利用するシークレット |
リソースオーナー | アカウント名 | このOAuthClientの持ち主 |
上記のような登録作業は、TwitterやFacebookでも同じように行います。PassportではTwitter,FacebookがStrategyとしてサポートされています。今回実装する内容と同じようなフローでTwitter,FacebookへのAPIアクセスが可能になります。
さて、登録した情報を利用し、OAuth 2.0によってAPIを叩いていきます。
3. OAuth 2.0で認可し、APIを叩いてみる
基本的には、リポジトリに記載されているサンプルコードに則って実装すればスムーズに出来ます。 ここでは実際にサンプルコードを実装した場合どのような挙動になるのかも踏まえて紹介いたします。
3-1. Expressの基盤を作る
Express Generatorでアプリケーションを生成します。
とりあえずHello Worldを表示するまで、チュートリアルを進めましょう。
express myapp cd myapp yarn yarn start
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 のログイン画面が表示されます。
ログインすると続いて認可画面が表示されます。これは、先程設定した Scope の利用を、ユーザーに同意してもらうための画面です。
認可を行うと、/
へリダイレクトされ、トップページに/me
の情報が表示されます。
さいごに
今回は 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の開発、及び利用するアプリケーション開発を行うエンジニアを募集しています。
*1:https://tools.ietf.org/html/rfc6749
*2:https://openid.net/specs/openid-connect-core-1_0.html
*3:Open Source Software : https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%BC%E3%83%97%E3%83%B3%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2
*4:2021/01/27現在、3ヶ月間の無償トライアルが利用可能