githubにpush出来なくなった

いい加減gitを使いこなしたい!と思い立ち、gitに慣れるためにgithubを使い始めたのですが、最初のpushはうまくいったものの2回目のpushがうまくいかなくなってしまいました。なんとかpushできるようになったので、その解決法をメモしておきます。
pushしてみたところ、

$ git push origin master
fatal: remote error:
  You can't push to git://github.com/bangyy/dotfiles.git
  Use git@github.com:bangyy/dotfiles.git

こんなこと言われてしまっていたのですが、いろいろ調べてみるとどうやら.git/configに問題があるようなので確認してみると、

$ cat .git/config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    ignorecase = true
[remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/*
    url = git://github.com/bangyy/dotfiles.git
[branch "master"]
    remote = origin
    merge = refs/heads/master

となっていました。
どうやら

    url = git://github.com/bangyy/dotfiles.git

が問題のようです。
ここを

    url = git@github.com:bangyy/dotfiles.git

と変更したところ、無事pushできました。いえーい。
うーん、慣れるためには積極的に使わないと始まらないとは思うんですけど、あんまりあやふやな感じで使ってるのも良くないので調べつつ覚えつつ使っていきたいですね

ジオタグ付きのtweetを表示するサービス tweez を公開しました

tweez
先々週ぐらいに、ジオタグが付いたtweetをリアルタイムで地図上に表示するサービスを公開しました。
位置情報を使って何かできたらなーと思っていたのと、WebScoket使ってみたいなーと思っていて、両方共実現できそうだったのでつくってみました。(MongoDBも使ってます。使ってみたかったので)

仕組みとか

仕組みとしては、サーバでTwitterのstreamingAPIを使用してひたすらジオタグの付いたtweetをDBに貯めて、Google Mapsで取得した緯度経度情報を使って、DBからtweetを取得しています。また、WebSocketを使用して一定間隔ごとに新着のtweetを取得しています。
WebSocketにはphp-websocketを使用しています。このライブラリですが、かなり簡単でsampleを見ていれば使えました。ひとまずWebSocket試してみたい人にはおすすめかもしれません。Socket.IOも使えます。
http://siriux.net/2010/08/php-websocket-server/
MongoDBは全然使いこなせていませんが、クエリが個人的には分かりやすく好きです。今度なにか作るときにも使ってみようかなあ。

というわけで

もしよければ使ってみてもらえると嬉しいです。
位置情報は面白いはずだし、せっかくジオタグ付きのtweetをDBに溜め込んでいることだし、また何か位置情報関連の別サービスでもつくってみようかと思ってます。再利用出来るものは再利用しましょう!

OAuth Echoを調べたのでメモ

前々から気になっていたOAuth Echoについて調べてみました。まだ試してませんが。
そんなわけで、調べたメモを。参考資料は OAuth Echo | Twitter Developers などで。仕様としてはOAuth Echo - Identity Verification Delegation (Draftの1枚のみのようです。

use case

個人的にOAuth Echoは何だか取っ付きにくかったのですが、use caseを想定して仕様を見てみると、そんなに難しいものでも無かったです。

OAuth Echoは、Consumer(twitter clientなど)がPhoto storage(twitpicなど)に写真を投稿するときなどに使われます。
twitpicに写真を投稿するにはtwitterの認証情報が必要になりますが、twitpicは当然そんなモノ持っていません。なので、twitter clientがtwitpicに対して、どのUserが写真を投稿したいのかを伝える必要があります。
その実現のために、twitter clientはヘッダにOAuth 1.0のauthorization headerに含むような値を別のヘッダに含めてtwitpicを送ってやります。twitpicはtwitter clientからのリクエストに含まれるheaderを用いて、twitter APIのaccount/verifiy_credentialsにリクエストすることで、リクエスト元のユーザー情報を取得できるようになります。twitter clientの持つUserのaccess tokenやconsumer keyなどを使ってtwitpicが代わりにtwitterにリクエストできるということです。ここら辺が"Echo"な感じ...なんだと思いますたぶん。

OAuth Echo

OAuth Echoの登場人物は

  • User
  • Consumer
  • Delegator
  • SP

の4者です。
前提として、ConsumerはUserから認可を与えられているものとします。以下、OAuth Echoのフローです。

  1. ConsumerがDelegatorのendpointにリクエストします。この時、headerに"X-Auth-Service-Provider"と"X-Verify-Credentials-Authorization"を指定します。
    • X-Auth-Service-ProviderにはSPにUserを特定するためのendpointを指定します。(twitterの場合はaccount/verifiy_credentials)
    • X-Verify-Credentials-AuthorizationにはX-Auth-Service-Providerで指定したendpointのAPIをリクエストするのに必要な値を指定します。この値は通常ConsumerがAPIをリクエストするときに指定するAuthorization headerの値です(e.g. OAuth oauth_consumer_key="...", oauth_token="...", oauth_signature_method="...", oauth_signature="...", oauth_timestamp="...", oauth_nonce="...", oauth_version="...")。
  2. Delegatorはポストされたデータを一時的に保存した後、X-Auth-Service-Providerで指定されたAPIを、X-Verify-Credentials-Authorizationで指定された値をAuthorization headerに指定してリクエストします。
  3. SPはDelegatorのリクエストを通常のOAuth APIリクエストとして処理します。レスポンスのhttp status codeが2xxなら有効なリクエスト、そうでなければ無効なリクエストとして判断されたことになります。リクエストが成功した場合、SPはUserの情報をレスポンスに含めます。
  4. DelegatorはUserの情報を取得できたので、さっき一時的に保存したデータをUserと紐付けて保存することができます。

"DelegatorがUserの情報を必要とするけど、Consumerが勝手に送ってきたUser情報で保存するわけにいかないし、じゃあどうやってvalidなUser情報を取得するの?"という問題の解決策のようです。
また、リクエストするAPIに付加するsignatureはConsumerが指定しているので、Delegatorに勝手にUser情報を変更されることもありません。
ちなみに、"X-Auth-Service-Provider"と"X-Verify-Credentials-Authorization"はheaderでなくてPOSTしてもいいようです。推奨はされていないようですが。

OAuth Echo Restricted

通常のOAuth Echoよりセキュアなパターンです。
このFlowでは先程の1.で指定するheaderに加え、"x_delegator"にDelegatorの名前を指定します。
このFlowがなぜセキュアかというと、"X-Verify-Credentials-Authorization"の値(=Authorization headerの値)に含まれる"OAuth_signature"の生成にx_auth_service_providerとx_delegatorを含める必要があるので、Delegatorを完全に固定することができます(通常のOAuth Echoでは、もしDelegatorがリクエストに含まれる"X-Verify-Credentials-Authorization"の値を第三者に渡していたら、第三者がUserの情報を取得できてしまいます)。
また、SPがどのDelegator経由でリクエストが来たのかを把握できるのもポイントなのかもしれません。

まとめ

オープンな仕様にしようとしているみたいですが、twitter以外に採用しているSPあるんでしょうか。twitter向けな感じが否めないですし。twitterみたいにエコシステムが発達していれば使われることもあるんだろうけど...。
ただ、こういった仕様のニーズはあるのかなーとか思ったりします。

Facebookが採用してるOAuth2.0の仕様を調べてみた

Facebook流行って?ますね。
あまり使っていないですけど。
で、Facebookと言えば、いち早くOAuth2.0を採用していたりします。
そんなわけで、Facebookの採用している仕様を調べてみました。
乗ってるものには乗っていけの精神です。

Facebookの仕様は
Authentication - Facebook developers
OAuth 2.0はこちら
draft-ietf-oauth-v2-10 - The OAuth 2.0 Authorization Framework

Flow

Facebookはweb applicationを対象にしたFlow以外に

  • JavaScript-based authentication
  • Desktop application authentication
  • Mobile Web authentication
  • Canvas Applications (beta)

の4つのタイプをサポートしているようです。

今回はweb application flowのみ調べてみました。

Authorization

authZ endpointは
https://graph.facebook.com/oauth/authorize
パラメータは

parameter required?
client_id required
redirect_uri required
scope option
display option

となっています。
displayはFacebook独自のパラメータです。

URIを作成すると、

https://graph.facebook.com/oauth/authorize?client_id=...&redirect_uri=http://www.exaple.com/oauth_redirect

こんな感じになります。

scope

デフォルトでもいろいろとリソースは取得できますが、scopeパラメータを追加することで取得できるリソースが拡張されます。
scopeには追加したいpermissionを,区切りで指定します。
(OAuth2.0ではspace-delimitedとなっているのでそっちも試してみたところ一応出来ました。)
scopeの詳しい仕様はPermissions Reference - Facebook developersに載ってます。

display

displayパラメータを指定することで認可ページの表示方法を指定できるようです。

# page - Display a full-page authorization screen (the default)
# popup - Display a compact dialog optimized for web popup windows
# wap - Display a WAP / mobile-optimized version of the dialog
# touch - Display an iPhone/Android/smartphone-optimized version of the dialog

こんな感じ。
display parameterはOAuth2.0には無い仕様です。

access tokenの取得

認可ページでユーザーが許可をするとauthZ endpointで指定したredirect_uriにユーザーは遷移します。
redirectされるときにcodeパラメータがクエリパラメータとして付加されているので、このcodeと交換でaccess tokenを取得します。

token endpointは
https://graph.facebook.com/oauth/access_token
パラメータは

parameter required?
client_id required
client_secret required
redirect_uri required
code required

となっています。

URIを作成すると、

https://graph.facebook.com/oauth/access_token?client_id=...&redirect_uri=http://www.example.com/oauth_redirect&client_secret=...&code=...

という感じになります。

OAuth 2.0の仕様としてはaccess token取得時のmethodはPOSTだけど、FacebookはGETのようです。
また、この時のResponseもOAuth 2.0の仕様ではjsonですが、

access_token=...&expires=...

という感じの文字列が返ってきました。

APIリクエスト

こんな感じで

https://graph.facebook.com/me?access_token=...

OKです。簡単!

その他

authZ endpointでユーザーが拒否した場合はredirect_uriで指定したuriにユーザーを遷移させますが、このときerror_reasonというparameterを付加してくれます。error_reasonというパラメータも特にOAuth2.0の仕様で規定されているものではないです。

また、Facebookはrefresh tokenの発行はしませんが、offline_access permissionがないと access tokenに有効期限が設定されるそうです。で、scopeにoffline_access permissionを追加しておくと有効期限がなくなるとのこと。ちなみに、ユーザーがpasswordを変更するとoffline_access permissionがあっても無効になります。

あと、やってて気づいたのですが、codeとaccess tokenの交換は何度でもできます。取得できるaccess tokenの値は同一ですが、offline_access permissionを付加しない場合、expiresの値がだんだん減っていきます。

まとめ

今回はここまで。
access tokenを取得する部分が案外最新のOAuth2.0の仕様と異なっていました。レスポンスがjsonじゃなかったり、リクエストもパラメータをクエリパラメータとして付加するようになっていたり。

OAuth 2.0のアップデートを追いかけているようなので、完全に最新の仕様と同一にはならないということなんでしょうか。

他にもいろいろ気になるところがあるけど、それはまた今度。

はじめまして

新年あけましておめでとうございます。
新年早々風邪引いたんで正月気分は1日ぐらいしか味わってないですけど。
あげく、1日会社休むとか散々でした。


そんなわけで、
年も明けたし、自分なりに新年の目標を立てたところ、
「よしブログはじめよう」となりました。唐突です。
というのも、
どうも自分にはログに残していくという癖が中々定着しないので、
ブログにでも作業のログを残していくこうと思いたったわけです。
これを機にログを付ける癖がつけばいいなぁ。


ブログの内容は作業のログとか、発見したこととか、調べたこととか、
そんなんを軸にしていけたらなぁと。
はてな記法も早いとこ把握しときたいです。
というより何より、気軽に書いていきましょう気軽に

そんなわけで

どうぞよろしくお願いします。