Cocoa/CocoaTouchからRemember The Milk APIを使ってみる(その2:APIの呼び出しと署名)
さて、MD5で何に署名するのかというわけで、APIの呼び出し。
こんなフォーマットでメソッドとパラメータを送る。GETでもPOSTでもいい。
http://www.rememberthemilk.com/services/api/request.rest.rtm
http://api.rememberthemilk.com/services/rest/?method=rtm.test.echo&api_key=123456789&name=value
これをただ送信するわけではなくて、次のような作法で署名する。
http://www.rememberthemilk.com/services/api/authentication.rtm
キー/バリューペアを結合し、Shared Secretと結合する。
abc=baz feg=bar yxz=foo
これを結合して
abcbazfegbaryxzfoo
Shared Secret(API Keyの申請をするともらえる)を前にくっつける
BANANASabcbazfegbaryxzfoo
MD5の値を求めて、パラメータに付加する。
BANANASabcbazfegbaryxzfoo
こういう文字列から、前回書いたメソッドでMD5値を求めて、パラメータに付加する。3
http://api.rememberthemilk.com/services/rest/?method=rtm.test.echo&api_key=123456789&name=value&api_sig=zxy987
ソースコード
私が書いたコードでNSURLRequestを作るとこんな感じ。POST。cachePolicyだのtimeoutIntervalは適当。
- NSDictionary *requestKeyValue
- パラメータを入れておく
- NSString *methodString
- RTM APIのメソッドを入れておく
- __apiKey
- API Keyを入れておく
- __sharedSecret
- Shared Secretを入れておく
- __authToken
- 認証でもらったトークンを入れておく
- __apiURL
- 送信先のURL(http://api.rememberthemilk.com/services/rest/)
NSMutableDictionary *mutableRequestKeyValue; if (requestKeyValue) mutableRequestKeyValue= [[requestKeyValue mutableCopy] autorelease]; else mutableRequestKeyValue = [NSMutableDictionary dictionary]; if (__apiKey) [mutableRequestKeyValue setObject:__apiKey forKey:@"api_key"]; if (__authToken) [mutableRequestKeyValue setObject:__authToken forKey:@"auth_token"]; [mutableRequestKeyValue setObject:methodString forKey:@"method"]; requestKeyValue = [[mutableRequestKeyValue copy] autorelease]; NSArray *keys = [requestKeyValue allKeys]; NSArray *sortedKeys = [keys sortedArrayUsingSelector:@selector(compare:)]; NSMutableString *apiSigInput = [NSMutableString string]; if (__sharedSecret) [apiSigInput setString:__sharedSecret]; NSMutableString *httpBody = [NSMutableString string]; for (NSString *key in sortedKeys) { NSString *value = [requestKeyValue objectForKey:key]; [apiSigInput appendString:key]; [apiSigInput appendString:value]; value = [value stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; if ([httpBody length] > 0) { [httpBody appendString:@"&"]; } [httpBody appendFormat:@"%@=%@", key, value]; } NSString *apiSig = [apiSigInput md5]; [httpBody appendFormat:@"&api_sig=%@", apiSig]; NSData *httpBodyData = [httpBody dataUsingEncoding:NSASCIIStringEncoding]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:__apiURL] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30]; [request setHTTPMethod:@"POST"]; [request setHTTPBody:httpBodyData];
で、実際にAPIを使う時はその前に認証をしなければならない。それは次回。