3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Rocket.Chat(Meteor)のGitHubログインをかなり無理やりAndroidのアプリからおこなう

Posted at

まえおき

Rocket.Chat というMeteorフレームワークを使った代表的なチャットアプリがあります。
Slackを自前の鯖に建てたい、みたいな人にはちょうどいいアプリです。

で、

  • こいつをAndroidから使えるようになったらいいなー
  • オープンソースやってます( ー`дー´)キリッといえる何かをやりたいなぁ

ということで、 Rocket.Chat.Android ってのを頑張って作ってみてます。

GitHubのOAuth使いたい!と思って、実装をこころみたところ、なかなか一筋縄ではいかない感じだったので、ちょっとメモっておきます。

Rocket.ChatのGitHub OAuthのフロー

1. サーバが対応してくれている場合のみ、WebSocketからGitHubのクライアントIDが流れてくる

send: {"msg":"sub","id":"hogehogehogeho1","name":"meteor.loginServiceConfiguration","params":[]}

receive: {"msg":"added","collection":"meteor_accounts_loginServiceConfiguration","id":"JMBQZo25cKkcgkzNB","fields":{"service":"github","clientId":"886a7b2a1fb067b10d3a"}}

receiveは他にもTwitterとかFacebookとかGoogleとかも、対応してたら流れてきます。

2. stateを生成する

Meteorのソースをみてみたところ、以下の様な方法でstate(GitHubのOAuthのときに渡す乱数パラメータてきなやつ)を生成しているみたいです。

meteor//packages/oauth/oauth_client.js
OAuth._stateParam = function (loginStyle, credentialToken, redirectUrl) {
  var state = {
    loginStyle: loginStyle,
    credentialToken: credentialToken,
    isCordova: Meteor.isCordova
  };

  if (loginStyle === 'redirect')
    state.redirectUrl = redirectUrl || ('' + window.location);

  // Encode base64 as not all login services URI-encode the state
  // parameter when they pass it back to us.
  // Use the 'base64' package here because 'btoa' isn't supported in IE8/9.
  return Base64.encode(JSON.stringify(state));
};

こいつが若干やっかいで、

  • 毎度違うものをわたさないといけない
  • データの整合性は取れている必要がある

で、ちょっとloginStyleあたりのソースもあわせて読みつつ、
コンソールで↓のようにたたくことで生成できるっぽいことがわかりました。

state生成
echo '
  var state = {
    loginStyle: "popup",
    credentialToken: "hogehogehogehogehogehoge"+(new Date()-0),
    isCordova: true
  };

console.log(JSON.stringify(state)); ' | node | base64

credentialTokenは、毎回違う値が渡せていれば、かなりてきとういいです。

3. GitHub APIをWebブラウザで開く

https://github.com/login/oauth/authorize?client_id=886a7b2a1fb067b10d3a&scope=user%3Aemail&redirect_uri=https://demo.rocket.chat/_oauth/github?close&state=eyJsb2dpblN0eWxlIjoicG9wdXAiLCJjcmVkZW50aWFsVG9rZW4iOiJob2dlaG9nc2Zzb2RpZmpkc2hvZ2UxNDQ4OTk1MjcyMjcxIiwiaXNDb3Jkb3ZhIjp0cnVlfQo=

こんなかんじの、ながーーいURLをブラウザで開いて、OAuth認証・認可をします。
(※ ユーザ操作がともないます)
 
 
パラメータをちょっとだけ整理すると、↓のようなかんじ。

key | value | 備考
-------------+----------------------------+--------------------------
client_id | 886a7b2a1fb067b10d3a | WebSocketから流れてきたやつ
redirect_uri | [host]/_oauth/github?close | ReadMeにかいてあった
scope | user:email |
state | eyJsb2dpblN.......Qo= |手順2で生成したやつ

4. リダイレクト先のWebページのHTMLを見る

認可が完了すると、白紙のWebページにとばされます。が、HTMLは書いてあって、
↓のようなコードがあります。

  <div id="config" style="display:none;">{"setCredentialToken":true,"credentialToken":"hogehogsfsodifjdshoge1448994999884","credentialSecret":"-bK92Xpv9AMQA3VTdwSB94cF6paLIFVxH8OqWzr50wT","storagePrefix":"Meteor.oauth.credentialSecret-","isCordova":true}</div>

configのなかの、credentialTokenとcredentialSecretを使います

5. ログイン!

send:{"msg":"method","method":"login","params":[{"oauth":{"credentialToken":"hogehogsfsodifjdshoge1448995272271","credentialSecret":"juN7gw7FsLopboQpUnLW4Lz1MpCDCRnnaF9PuQQFtXS"}}],"id":"123sdfiuh3e"}

receive:{"msg":"added","collection":"users","id":"wffqrSXNojgMnuz8v","fields":{"emails":[{"address":"xxxxxxxxx@crowdworks.co.jp","verified":true}],"username":"YusukeIwaki"}}
receive:{"msg":"result","id":"123sdfiuh3e","result":{"id":"wffqrSXNojgMnuz8v","token":"YmebU............Q5n","tokenExpires":{"$date":1456771391735}}}

って感じで、tokenが得られたら成功です!
次回からはこのtokenを使えば、ブラウザを開く必要はありません。

おわりに(ひとりごと)

Rocket.Chatの手順で説明しましたが、Meteor使ってるアプリならコールバックURL以外は基本的な流れは一緒だと思います。

とはいえ、細かすぎてワケガワカラナイヨ って感じですね・・・
MeteorにGitHubログインのためのREST APIだれかつくって・・・

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?