easyAuthを使ってAzure FunctionsでTwitter OAuth認証付きのAPIを作る。

Azure Functionsには認証認可を扱うeasyAuthと呼ばれる機能があり、ここでその使い方について紹介する。

Azure Functions は、Azure Web Appがベースとなっていて、だいたいWeb App で出来ることはFunctionsでもできる。 Web Appには、TwitterFacebookなどの外部での認証と連携させる機能を持っており、それを利用し、アプリケーションの認証機能部分を作ることができる。 また、Token Storeを利用することで、認証したユーザーのAccess Tokenも保存し、特別なライブラリを使用することなくそのAccess Tokenを利用することができる。

それらを試すために、Twitter OAuthを利用した認証付きのツィートを投稿するAPIをAzure Functionsアプリを作ってみた。

github.com *1

ちなみに、Vue.jsで作ったフロントを組み合わせたものが、こちら。

takoyaki.netlify.com

もくじ

前提

予めAzure Functionsのアプリが1つあること。 以降、文中ではsamplefuntionとして参照する。

Twitter にアプリケーションを登録

Twitter Developers を開き、アプリケーションを登録する。 登録するCallback URLは、 https://samplefunction.azurewebsites.net/.auth/login/twitter/callback を入れる。 これは、あとで設定するeasyAuthが追加するCallback用のエンドポイントのURLである。

他の必須項目を入力して登録後、発行されたConsumer API KeyとAPI Secret Keyを控えておく。

Azure Functions の認証/認可の設定

Azure Portal から、Azure Functions のブレードを開き、Authentication/Authorization から以下のように設定する。

f:id:satoryu:20190404193101p:plain

easyAuthによる認証

ログイン

https://samplefunction.azurewebsites.net/.auth/login/twitter をブラウザで開くと、TwitterOAuth認証画面にリダイレクトされる。 ここで先程登録したアプリケーションにTwitterアカウントで認証することができる。

ログアウト

https://samplefunction.azurewebsites.net/.auth/logout にアクセスすることで、ログアウトができる。

Access Tokenの利用

認証後に特別なライブラリを利用することなくAccess TokenをFunctionアプリは取得することができる。

具体的には、Twitterで認証した後に、ドメインsamplefunction.azurewebsites.netに対してAppServiceAuthSessionというCookieが発行される。このCookieを付けて、Azure Functionsアプリにリクエストを送ることで認証済みとして扱われる。 そして、アプリケーションへのリクエストに下記のヘッダが追加される。

  • X-MS-TOKEN-TWITTER-ACCESS-TOKEN
  • X-MS-TOKEN-TWITTER-ACCESS-TOKEN-SECRET

これはそれぞれAccess TokenとAccess Token Secretなので、Consumer KeyとConsumer Secretと組み合わせることで、Twitter RESTful APIを認証済みのユーザーとして利用することができる。

実際のコード

実際にこの仕組を利用して、Twitterに投稿するためのFunctionのコードを載せる。

takoyaki-api/index.js at master · satoryu/takoyaki-api · GitHub

const Twitter = require('twitter')

module.exports = async function (context, req) {
    const status = req.body.status
    const twitter = new Twitter({
        consumer_key: process.env.TWITTER_CONSUMER_KEY,
        consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
        access_token_key: req.headers['x-ms-token-twitter-access-token'],
        access_token_secret: req.headers['x-ms-token-twitter-access-token-secret']
    })

    try {
        const tweet = await twitter.post('statuses/update', { status })
        context.bindings.res = { body: tweet }

        context.done()
    } catch(err) {
        context.log.error(err)
        context.bindings.res = {
            status: 500,
            body: err
        }
        context.done(err)
    }
};

ここでは、twitterというパッケージを利用して、Twitter APIへアクセスしている。 それを利用する際に、環境変数からConsumer Key、リクエストに追加された2つのヘッダからAccess Tokenを用いている。 環境変数TWITTER_CONSUMER_KEYTWITTER_CONSUMER_SECRET は予めFunctionアプリのApp Settingsから追加しておく必要がある。

おわりに

easyAuthによる認証とToken Storeを使うことで、OAuthの認証の実装や認証後に得られるAccess Tokenの管理をする必要がなく、DBを準備することもなく、アプリケーションの開発に集中することができる。

easyAuthをローカルの開発環境で起動(もしくは再現)させる方法をまだ見つけられていないので、テストする際には実際にデプロイしなければならないところが課題として残っている。 もしご存知の方がおりましたら教えてください。

参考

開発者の@cgillum のeasyAuthのWikiに詳しく書いてある。

github.com

また、Web App の公式ドキュメントにも認証と認証後のAccess Tokenの扱い方について書いてある。

docs.microsoft.com

*1:なぜタコ焼きにしたのかはよく覚えてない。「つぶやき」をもじっただけ。