R OAuth for twitteR @twittoru
R OAuth for twitteR@twittoru
Who am I
• @twittoru
• id:tor_ozaki
• 頭狂濃厚大学高額部伝記伝師講学科 B4
Tsukuba.R
• #1 初参加
• #2 プログラミングを⑨ミリも知らない俺がRでProject Eulerに挑戦してみた
• #3 それRじゃなくてもできるよ 多言語と組合せて最高にキモいコードを書こう!
• #4 見てただけ
• #6 Rubyで学ぶ 奇妙な 関数型 プログラミング言語
Objective
• OAuth Consumer の R による実装
• 副読本 http://gist.github.com/586468
open authoRization
• in the document of ‘twitteR’ (Sep. 9, 2010)
DescriptionAs of July 2010, Twitter has changed their authentication structure to require OAuth. Until such a time that OAuth authentication is enabled in R and/or this requirement changes, these functions will not work properly.
“
,,OAuth logo, copyright: Chris Messina
http://wiki.oauth.net/Logo
BAuth vs. OAuth
• Basic Authorization
• Authorization: Basic BoRScHt0141=
• OAuth
• Authorization: OAuth oauth_consumer_key="misopASTE",oauth_token="CoCoapowder”, oauth_signature_method="HMAC-SHA1",oauth_signature="AndreISergeivicHKaliniNSaNMajIKakkoiIDesu%20”
(ry
OAuth logo, copyright: Chris Messinahttp://wiki.oauth.net/Logo
on Informality...
マネージャ経由で認証ページを出す
ログインした状態で見る
ワンタイムパスワードが出る
それを使って芸名を得る
以降は芸名でマネージャを通して活動
Requirements
• Header parameters
• Two type *_token and *_secret
• The signature
Header parameters
• oauth_consumer_key
• oauth_token
• oauth_timestamp
• oauth_nonce
• oauth_version
• oauth_signature_method
• oauth_signature
Params in R• data.frame
• declare: data.frame(key=c(...),value=c(...))
• addition: rbind(df,data.frame(...))
• name-vector: df[,1] #type factor
• list, vector
• declare: list(oauth_nonce=”skddsklfjslkdf”,...)
• addition: append(lis,list(...))
• name-vector: names(lis) #type character vector
Header parameters
• oauth_consumer_key:
• oauth_token:
• oauth_timestamp:
• oauth_nonce:
• oauth_version:
• oauth_signature_method:
• oauth_signature:http://dev.twitter.com/apps/xxxxxxx
Header parameters
• oauth_consumer_key:
• oauth_token:
• oauth_timestamp:
• oauth_nonce:
• oauth_version:
• oauth_signature_method:
• oauth_signature:
http://dev.twitter.com/apps/xxxxxx
OR
api.twitter.com/oauth/request_token↓
api.twitter.com/oauth/access_token↓
GET
TOP SECRET
Tokens and Secrets
• consumer_key, consumer_secret
• Application’s ID and password
• access_token, token_secret
• Another user’s ID and password
• *_secret are used as HMAC key
Header parameters
• oauth_consumer_key:
• oauth_token:
• oauth_timestamp:
• oauth_nonce:
• oauth_version:
• oauth_signature_method:
• oauth_signature:
background image, copyright: Bob Lordhttp://en.wikipedia.org/wiki/File:Enigma-rotor-stack.jpg
> as.integer(Sys.time())[1] 1284827757
> paste(+ letters[runif(20,1,27)],+ collapse=""+ )[1] "zdlygxbovmmzgvhnjoxe"
Header parameters
• oauth_consumer_key:
• oauth_token:
• oauth_timestamp:
• oauth_nonce:
• oauth_version:
• oauth_signature_method:
• oauth_signature:
“1.0”
YOU ARE (NOT) ALONE.
http://www.moviechronicles.com/neon-genesis-evangelion/
Header parameters
• oauth_consumer_key:
• oauth_token:
• oauth_timestamp:
• oauth_nonce:
• oauth_version:
• oauth_signature_method:
• oauth_signature:
oauth_signature_method“HMAC-SHA1”
in Twitter
Signature
• HMAC msg
• postfield: status=Tsukuba.R#8
• name1=value1&name2=value2&...
• http method (GET or POST)
• request uri (http://api.twitter.com/1/...)
• HMAC key
• ‘consumer_secret’&‘token_secret’
Signature base string
POST&http%3A%2F%2Fapi.twitter.com%2F1%2Fstatuses%2Fupdate.xml&oauth_consumer_key%3DOFOh7TGi2nKXSP6e7O1gYQ%26oauth_token%3DrtnZrA5LlbwfN4MRPBHC7gFp1ZI12JHTaX6gbJ4IbQ%26oauth_nonce%3Dcmncsfdzftpunyircetl%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1284744968%26oauth_version%3D1.0%26status%3Dhoge
POST&http%3A%2F%2Fapi.twitter.com%2F1%2Fstatuses%2Fupdate.xml&oauth_consumer_key%3DOFOh7TGi2nKXSP6e7O1gYQ%26oauth_token%3DrtnZrA5LlbwfN4MRPBHC7gFp1ZI12JHTaX6gbJ4IbQ%26oauth_nonce%3Dcmncsfdzftpunyircetl%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1284744968%26oauth_version%3D1.0%26status%3Dhoge
Signature base string
Request method
Request URL
URLEncode(join(sort(append(params, postfields)), “&”))
SBS in R
JoinParams <- function(name,params) { paste(name, params[name], sep="=")}params.string <- uriEncode(paste( sapply(sort(names(params)), JoinParams)), collapse="&"))uri <- uriEncode(uri)request_method <- toupper(method)paste(c(request_method, uri, params.string), collapse="&")
Trap
© 2008 Valve Corporation. All rights reserved. Valve, the Valve logo, Portal, the Portal logo, Portal: Still Alive, the Portal: Still Alive logo and Source are trademarks and/or registered
trademarks of Valve Corporation in the United States and other countries.
# R> utils::URLencode(“あいうえお”)[1] "%e3%81%82%e3%81%84%e3%81%86%e3%81%88%e3%81%8a"
# RubyURI.encode("あいうえお")# JavascriptencodeURI(“あいうえお”)=> "%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A"
HMAC in R
• HMAC ?
• H(K XOR opad, H(K XOR ipad, text))
• HMAC-SHA-1 → 通常の3倍 SHA-1
• CRAN Libraryェ…
H: hash functionK: hashed keytext: msgipad: 0x36, opad: 0x5c
library(digest)
• digest(“hoge”,algo=‘sha1’,serialize=FALSE)
• "31f30ddbcb1bf8446576f0e64aa4c88a9f055e3c"
• !! digest() returns only hexdigest 別になくても倒せる
digest de HMAC
• Bitwise operation (XOR)
• intToBits(i), rawToBits(charToRaw(ch))
• Hexdigest ←→ Digest
• strtoi(substring(digest, 1:x*2-1, 1:x*2, 16))
• see gist
API打叩撃打叩打叩撃
Authorization Header
• ≒signature base string without uri/method
• HTTP HeaderAuthorization: OAuth oauth_consumer_key="AzunyanPerOpEropeRoPero2828282", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1284868944", oauth_nonce="uqnitrqgwoejtyxoiqfm", oauth_version="1.0"
Authorization Header
• ≒signature base string without uri/method
• Authorization: OAuth oauth_consumer_key="AzunyanPerOpEropeRoPero2828282", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1284868944", oauth_nonce="uqnitrqgwoejtyxoiqfm", oauth_version="1.0"
separater “,”
Request method“” quote
HTTP in R
con <- make.socket('api.twitter.com',80) ; crlf <- "\r\n"write.socket(con,paste( 'POST ', '/1/statuses/update.xml',' HTTP/1.1',crlf, 'Host: ', 'api.twitter.com',crlf, 'Accept: */*', crlf, 'Authorization: ', oauthHeader(params),crlf, 'Content-Length: ', length(charToRaw(paste("status",tweet,sep="="))),crlf, 'Content-Type: application/x-www-form-urlencoded',crlf,crlf, ‘status=',tweet,crlf,sep=""))
ORZ
library(RCurl)
curlPerform(url=”http://api.twitter.com/1/statuses/update.xml”, httpheader=c(Authorization=oauthHeader(params)), postfields=paste("status=",tweet,sep=""))
ね、簡単でしょう?
Conclusion
• List & String processing
• あーるったらさいきょーね
実演
• できるかな
Test
• Tweet and Destroy
• つぶやく
• さくじょ
• やってみる
statuses/update
“ありすちゃんとてれすくんが
可愛すぎて生きてるのが辛い”
image from http://www.aist.go.jp/aist_j/science_town/intro.html※産総研ありす、産総研てれすは独立行政法人 産業技術総合研究所の登録商標です
つまり• URI: http://api.twitter.com/1/statuses/update.xml
• method: POST
• status=%E3%81%82%E3%82%8A%E3%81%99%E3%81%A1%E3%82%83%E3%82%93%E3%81%A8%E3%81%A6%E3%82%8C%E3%81%99%E3%81%8F%E3%82%93%E3%81%8C%E5%8F%AF%E6%84%9B%E3%81%99%E3%81%8E%E3%81%A6%E7%94%9F%E3%81%8D%E3%81%A6%E3%82%8B%E3%81%AE%E3%81%8C%E8%BE%9B%E3%81%84
(,ΦДΦ)デストローイ!
statuses/destroy/:id
• 脳量子波が乱れるので発言を消す
つまり
• URI: http://api.twitter.com/1/statuses/destroy/:id.xml
• method: POST
• id=xxxxxxxxxx
おしまいS4 classとかきちんと使ってtwitteRに組み込んで
CRANデビューしませんか ?