蟻地獄

Twitterに書ききれない長めの文とか書くよ

マストドンのOAuth認証でログインできるWebアプリの作り方

マストドンにpixivアカウントとかでログインするほうじゃなくて、自分が作ったWebアプリにマストドンアカウントでログインする機能を付けるほう。 完成品はこちら。 concept-auction.appspot.com

OAuth2準拠のAPIなのでTwitterログインとかとほぼ同じですが、大きな違いが2つあります。

1. ユーザーにドメインを入力してもらう必要がある

Twitterの場合は https://api.twitter.com/oauth/authorize を決め打ちで叩けばよかったんですが、マストドンインスタンスは自由に立てられるので、ただボタンが押されただけだとどのインスタンスにリクエストを投げればよいか分かりません。なので、ユーザーにマストドンインスタンスドメインを入力してもらう必要があります。 というわけでこんな感じのUIになりました。 f:id:mitomemel:20170422143231j:plain

2. client_id/client_secretはインスタンスごとに必要

新規にWebアプリを作る場合、Twitterだと https://apps.twitter.com/ でアプリ情報を登録してclient_id/client_secretを発行してもらっていましたが、マストドンの場合、どのインスタンスのユーザーが来るか分からないので事前にアプリ情報を登録しておくことができません。 ではどうするのかというと、新しいドメインのユーザーがログインしてきたタイミングでアプリ情報の登録もその場でREST APIを叩いて行います。一度発行したclient_id/client_secretとドメインの組は自サイトのDB等に保存しておきます。 大まかな流れは以下の通りです。

  1. ユーザーはドメインを入力してログインボタンを押す
  2. ログインリクエストを受け取ったWebアプリサーバは、まず自サイトに保存してあるclient_id/client_secretをドメイン文字列をキーに検索する。データが見つからなかった場合は指定されたドメインの /api/v1/apps を叩いてアプリ情報を登録し、発行されたclient_id/client_secretを自サイトのDBに保存後クライアントにclient_idを返す
  3. クライアントは受け取ったclient_idをパラメータに指定してマストドンサーバの /oauth/authorize にアクセスする
  4. ログイン画面が表示されるのでメールアドレス/パスワードを入力する f:id:mitomemel:20170422143251j:plain
  5. アカウントへのアクセス要求画面が表示されるので承認を押す f:id:mitomemel:20170422143311j:plain
  6. アプリ情報登録時に設定したredirect_uriが認証コード付きで叩かれるので、Webアプリサーバからマストドンサーバの /oauth/token を叩いてアクセストークンを受け取る
  7. アクセストークンを用いて /api/v1/accounts/verify_credentials を叩いてユーザー情報を入手

ただ、マストドンサーバ側のDBデータがDocker神の荒ぶりによって消えてしまった場合が厄介で、2.で自サイトに以前に保存されたclient_idをマストドンサーバに投げたらそんなclient_id知らねえよって言われてしまうので、再度アプリ情報を登録するみたいなエラーハンドリングが必要になります。うわあめんどくさい。

ちなみに今回はGAE/Goで作ったんですが、マストドンAPIへのアクセスにはgo-mastodonを使わせていただきました*1golang最高!

*1:go-mastodonはまだパスワード認証しか対応していないので、OAuthを使用するには若干手を入れる必要があります