実験はうまくいきました。
ところで、このコードには、とりあえずテスト用ということで、
consumer_keyとconsumer_secretが平文で書き込まれています。
認証後、oauth_tokenとoauth_token_secretもファイルに平文で書き込みます。
そこで、もし、これらの情報がウィルスや操作ミスなどで外部に漏れてしまった場合の影響が気になりました。
これらの情報が漏れると、アカウントが乗っ取られたりするのでしょうか?
例えばこのサイト
http://www30.atpages.jp/sumirexxx/sumir ... %82%B9.txt
にも
>Keep the "Consumer secret" a secret. This key should never be human-readable in your application.
と書いてあるので、気になります。
教えていただければ幸いです。
よろしくお願いします。
参考までに書いたコードを載せておきます。
► スポイラーを表示
#!/usr/bin/perl
# http://oauth.net/core/1.0/#anchor30
# http://adiary.blog.abk.nu/0276
# http://sayama-yuki.cocolog-nifty.com/blog/2009/09/twitteroauth-d7.html
# http://www.tumblr.com/tagged/perl?before=1297688293
# http://d.hatena.ne.jp/perlcodesample/20100427/1270894115
use Digest::SHA::PurePerl;
use JSON 'from_json';
#自分のconsumer_keyとconsumer_secret
$consumer_key="";
$consumer_secret="";
#開くブラウザとコマンドライン(%sがURLになる)
$browser='"C:\Program Files\Mozilla Firefox\firefox.exe" "%s"';
#Shift-JISからUTF8に変換するか(最初からUTF8な環境なら0にする)
$convert_utf8=1;
#生のサーバーから取得したデータを保存するか(テスト用)
$dump_response=0;
if($convert_utf8) {
require "sutf8.pl";
}
srand;
@mozi=("0" .. "9" , "A" .. "Z" , "a" .. "z");
$oauth_nonce="";
for($i=0;$i<19;$i++) {
$oauth_nonce .= $mozi[int(rand(62))];
}
$timestamp=time();
if(@ARGV==0) {
#リクエストトークンの取得
$signature_msg1="POST";
$signature_msg2="http://twitter.com/oauth/request_token";
$signature_msg3=
"oauth_consumer_key=$consumer_key&" .
"oauth_nonce=$oauth_nonce&" .
"oauth_signature_method=HMAC-SHA1&" .
"oauth_timestamp=$timestamp&" .
"oauth_version=1.0";
$signature_msg=&make_signature($signature_msg1,$signature_msg2,$signature_msg3);
$oauth_signature=&hmac_sha1("$consumer_secret&",$signature_msg)."=";
$oauth_signature=&urlencode($oauth_signature);
$request_auth=
"realm=\"\"," .
"oauth_consumer_key=\"$consumer_key\"," .
"oauth_nonce=\"$oauth_nonce\"," .
"oauth_signature=\"$oauth_signature\"," .
"oauth_signature_method=\"HMAC-SHA1\"," .
"oauth_timestamp=\"$timestamp\"," .
"oauth_version=\"1.0\"";
$http_request=
"POST /oauth/request_token HTTP/1.1\r\n".
"Host: twitter.com\r\n".
"Connection: close\r\n".
"Content-Type: application/x-www-form-urlencoded\r\n".
"Content-Length: 0\r\n".
"Authorization: OAuth $request_auth\r\n".
"\r\n";
$http_responce=&http_send("twitter.com",$http_request);
($header,$body)=split(/\r\n\r\n/,$http_responce,2);
if($header !~ /^HTTP\/[0-9]+\.[0-9]+ +200/) {
print "Authorization Failed.\n";
($result,$other)=split(/\r\n/,$header,2);
print $result."\n";
print $body;
exit(1);
}
%response=&response_decode($body);
open(FILE,"> oauth_temp.txt") or die("File open error.\n");
print FILE $response{'oauth_token'}."\n";
print FILE $response{'oauth_token_secret'};
close(FILE);
$browser_cmd=sprintf($browser,
"http://twitter.com/oauth/authorize?oauth_token=$response{'oauth_token'}");
system($browser_cmd);
} elsif(@ARGV>=2) {
if($ARGV[0] eq "-o") {
#アクセストークンの取得
$verifier=$ARGV[1];
open(FILE,"< oauth_temp.txt") or die("File open error.\n");
$oauth_token=<FILE>;
$oauth_token_secret=<FILE>;
chomp($oauth_token);
chomp($oauth_token_secret);
close(FILE);
unlink("oauth_temp.txt");
$signature_msg1="POST";
$signature_msg2="http://twitter.com/oauth/access_token";
$signature_msg3=
"oauth_consumer_key=$consumer_key&" .
"oauth_nonce=$oauth_nonce&" .
"oauth_signature_method=HMAC-SHA1&" .
"oauth_timestamp=$timestamp&" .
"oauth_token=$oauth_token&" .
"oauth_verifier=$verifier&" .
"oauth_version=1.0";
$signature_msg=&make_signature($signature_msg1,$signature_msg2,$signature_msg3);
$oauth_signature=&hmac_sha1("$consumer_secret&$oauth_token_secret",$signature_msg)."=";
$oauth_signature=&urlencode($oauth_signature);
$request_auth=
"realm=\"\"," .
"oauth_consumer_key=\"$consumer_key\"," .
"oauth_nonce=\"$oauth_nonce\"," .
"oauth_signature=\"$oauth_signature\"," .
"oauth_signature_method=\"HMAC-SHA1\"," .
"oauth_timestamp=\"$timestamp\"," .
"oauth_token=\"$oauth_token\"," .
"oauth_verifier=\"$verifier\"," .
"oauth_version=\"1.0\"";
$http_request=
"POST /oauth/access_token HTTP/1.1\r\n".
"Host: twitter.com\r\n".
"Connection: close\r\n".
"Content-Type: application/x-www-form-urlencoded\r\n".
"Content-Length: 0\r\n".
"Authorization: OAuth $request_auth\r\n".
"\r\n";
$http_responce=&http_send("twitter.com",$http_request);
($header,$body)=split(/\r\n\r\n/,$http_responce,2);
if($header !~ /^HTTP\/[0-9]+\.[0-9]+ +200/) {
print "Authorization Failed.\n";
($result,$other)=split(/\r\n/,$header,2);
print $result."\n";
print $body;
exit(1);
}
%response=&response_decode($body);
open(FILE,"> oauth.txt") or die("File open error.\n");
print FILE $response{'oauth_token'}."\n";
print FILE $response{'oauth_token_secret'};
close(FILE);
print "user_id: $response{'user_id'}\n";
print "screen_name: $response{'screen_name'}\n";
} elsif($ARGV[0] eq "-p") {
#投稿
$content=$ARGV[1];
if($convert_utf8){ &sjis2utf8(*content); }
open(FILE,"< oauth.txt") or die("File open error.\n");
$oauth_token=<FILE>;
$oauth_token_secret=<FILE>;
chomp($oauth_token);
chomp($oauth_token_secret);
close(FILE);
$display_coordinates=0;
$irtsi="";
if(@ARGV>=3) {
$irtsi=$ARGV[2];
}
$encode_content=&urlencode($content);
$form_data="status=$encode_content&trim_user=true";
if($irtsi){ $form_data.="&in_reply_to_status_id=$irtsi" }
$signature_msg1="POST";
$signature_msg2="http://api.twitter.com/1/statuses/update.json";
$signature_msg3=
"oauth_consumer_key=$consumer_key&" .
"oauth_nonce=$oauth_nonce&" .
"oauth_signature_method=HMAC-SHA1&" .
"oauth_timestamp=$timestamp&" .
"oauth_token=$oauth_token&" .
"oauth_version=1.0&" .
"status=$encode_content&" .
"trim_user=true";
if($irtsi) {
$signature_msg3="in_reply_to_status_id=$irtsi&".$signature_msg3;
}
$signature_msg=&make_signature($signature_msg1,$signature_msg2,$signature_msg3);
$oauth_signature=&hmac_sha1("$consumer_secret&$oauth_token_secret",$signature_msg)."=";
$oauth_signature=&urlencode($oauth_signature);
$request_auth=
"realm=\"\"," .
"oauth_consumer_key=\"$consumer_key\"," .
"oauth_nonce=\"$oauth_nonce\"," .
"oauth_signature=\"$oauth_signature\"," .
"oauth_signature_method=\"HMAC-SHA1\"," .
"oauth_timestamp=\"$timestamp\"," .
"oauth_token=\"$oauth_token\"," .
"oauth_version=\"1.0\"";
$http_request=
"POST /1/statuses/update.json HTTP/1.1\r\n".
"Host: api.twitter.com\r\n".
"Connection: close\r\n".
"Content-Type: application/x-www-form-urlencoded\r\n".
"Content-Length: ".length($form_data)."\r\n".
"Authorization: OAuth $request_auth\r\n".
"\r\n".
$form_data;
$http_responce=&http_send("api.twitter.com",$http_request);
($header,$body)=split(/\r\n\r\n/,$http_responce,2);
$data=from_json($body);
if($header !~ /^HTTP\/[0-9]+\.[0-9]+ +200/) {
print "Authorization Failed.\n";
($result,$other)=split(/\r\n/,$header,2);
print $result."\n";
print $data->{error}."\n";
exit(1);
}
print "Success.\n";
print $data->{created_at}."\n";
print "id: ".$data->{id_str}."\n";
} else {
print "Command line error.\n";
}
} else {
print "Command line error.\n";
}
#ライブラリ
sub urlencode {
local($input)=@_;
$input =~ s/([^0-9a-zA-Z\-\._\~])/sprintf("%%%02X",ord($1))/eg;
return $input;
}
sub response_decode {
local($query_string)=@_;
local(@a);
local($name,$value,$a);
local(%result)=();
@a = split(/&/, $query_string);
# それぞれの「変数名=値」について
foreach $a (@a) {
# イコール( = )で分解します
($name, $value) = split(/=/, $a);
# + や %8A などをデコードします
$value =~ tr/+/ /;
$value =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C", hex($1))/eg;
# 後で使用する場合は、$FORM{'変数名'} に代入しておきます
$result{$name} = $value;
}
return %result;
}
sub http_send {
local($host,$request)=@_;
local($response)=("");
local($addr,$name);
$addr = (gethostbyname($host))[4];
$name = pack("S n a4 x8", 2, 80, $addr);
socket(S, 2, 1, 0);
unless(connect(S, $name)){return "";}
binmode(S);
select(S); $| = 1; select(STDOUT);
print S $request;
$response="";
while (<S>) { $response .= $_; }
close(S);
if($dump_response) {
if(open(RESPONSE,"> http_response.txt")) {
binmode(RESPONSE);
print RESPONSE $response;
close(RESPONSE);
}
}
return $response;
}
sub make_signature {
local($msg1,$msg2,$msg3)=@_;
return &urlencode($msg1)."&".&urlencode($msg2)."&".&urlencode($msg3);
}
# http://adiary.blog.abk.nu/0274
sub hmac_sha1 {
# my $self = shift;
my ($key, $msg) = @_;
my $sha1;
if ($Digest::SHA::PurePerl::VERSION) {
$sha1 = Digest::SHA::PurePerl->new(1);
} else {
eval {
require Digest::SHA1;
$sha1 = Digest::SHA1->new;
};
if ($@) {
require Digest::SHA::PurePerl;
$sha1 = Digest::SHA::PurePerl->new(1);
}
}
my $bs = 64;
if (length($key) > $bs) {
$key = $sha1->add($key)->digest;
$sha1->reset;
}
my $k_opad = $key ^ ("\x5c" x $bs);
my $k_ipad = $key ^ ("\x36" x $bs);
$sha1->add($k_ipad);
$sha1->add($msg);
my $hk_ipad = $sha1->digest;
$sha1->reset;
$sha1->add($k_opad, $hk_ipad);
my $b64d = $sha1->b64digest;
$b64d = substr($b64d.'====', 0, ((length($b64d)+3)>>2)<<2);
return $b64d;
}※実行に必要なライブラリ
http://sato-si.at.webry.info/200603/article_6.html
http://search.cpan.org/dist/Digest-SHA-PurePerl/
http://search.cpan.org/dist/JSON/lib/JSON.pm