C/C++ã§Twitterã®XAuthèªè¨¼ãè¡ã
åç½®ã
ãªããæ¥ã«Twitterã«æ¸ãè¾¼ã¿ãè¡ãããã°ã©ã ãæ¸ããããªã£ãã®ã§ãã©ããªæ¹æ³ãããã調æ»ãã¦ã¿ã¾ããã
Twitterã®èªã¿è¾¼ã¿åä½ã«é¢ãã¦ã¯ç¹å®ã¦ã¼ã¶ã®ãã£ã¼ãæ
å ±ãåå¾ããã°è¯ãã ããªã®ã§ç°¡åã«å®ç¾ã§ãã¾ãããæ¸ãè¾¼ã¿åä½ã«ãªãã¨ã¦ã¼ã¶èªè¨¼ãå¿
è¦ã«ãªãã®ã§ãã§ããè¤éã«ãªãã¾ããèªè¨¼æ¹æ³ã¯å¤§ããããã¦ï¼ç¨®é¡(OAuthã¨XAuth)ããã¿ããã§ã(æã¯APIãå®è¡ãã度ã«èªè¨¼ãè¡ããã¼ã·ãã¯èªè¨¼ã£ã¦ã®ããã£ããããã§ã)ã
OAuthèªè¨¼ãXAuthèªè¨¼ã®ã¨ãã£ãèªè¨¼é¢é£ã®ä»çµã¿ãéãã«ã¤ãã¦ã¯ããã§èª¬æããªãã®ã§ä»ã®ãã¼ã¸ãåç
§ãã¦ãã ããã軽ã説æããã¨OAuthã¯Twitterï¼ã¦ã¼ã¶ï¼Webãµã¼ãã¹ã®3è
éã§ä½¿ãããèªè¨¼ã§ä¸»ã«Webãµã¼ãã¹ä¸ã§å©ç¨ãããæ¹å¼ãXAuthã¯Twitterï¼ã¦ã¼ã¶ã®2è
éã§ä½¿ãããèªè¨¼ã§ãã©ã¦ã¶æä½ã使ããªãã¹ã¿ã³ãã¢ãã¼ã³ããã°ã©ã ã§å©ç¨ãããæ¹å¼ã§ããã©ã¡ããã¦ã¼ã¶æ
å ±ã¨ãã¹ã¯ã¼ãæ
å ±ã«é¢é£ããæ
å ±ãæ¯åéä¿¡ããªãã¦æ¸ããããªããã¼ã«ãªã£ã¦ãã¾ãã(ã»ãã¥ã¢ãªHTTPã¯ããã¼ãã¤ã¡ã¼ã¸ãã¾ãã)
ããã«èª¿æ»ããçµæãTwitterã¯è²ã ãªè¨èªã§ã©ã¤ãã©ãªåããã¦ããããããåç´ãªæ¸ãè¾¼ã¿åä½ãããã ã£ããçµæ§ç°¡åã«å®è£ ã§ãããã ã¨ãããã¨ãå¤ãã¾ããããããWebãµã¼ãã¹ã®éçºè¨èªã¨ãã¦è¯ã使ãããPerlãPHPã®ãµã³ãã«ã³ã¼ãã¯è¦ã¤ãããã®ã®ãç®çã ã£ãC/C++ã§å®è£ ããæ¹æ³ã¯ãã¾ãç¡ãã£ãã®ã§ãä»åã¯C/C++ã®CUIããã°ã©ã ã§åä½ããããã«å®è£ ãã¦ã¿ããã¨æãã¾ããåè¿°ã®ã¨ããã¹ã¿ã³ãã¢ãã³ããã°ã©ã ã¨ãã¦å®è£ ããã®ã§XAuthãå©ç¨ãã¦èªè¨¼ããã¾ããTwitter-devãè¦ã¦ã¿ãã¨ãC/C++åãã®OAuthç¨ã©ã¤ãã©ãªã¨ãã¦liboauthã¨ãããã®ãæ¨å¥¨ããã¦ã¾ãããããã¯Twitterã«éå®ããããã®ã§ã¯ãªããOAuthã§èªè¨¼ãè¡ããµã¼ãã¹å ¨è¬ã§ä½¿ããã©ã¤ãã©ãªã¿ããã§ãããã¡ããXAuthã®ã©ã¤ãã©ãªã¨ãã¦ãå©ç¨ã§ãã¾ãã
C/C++ã§å®è£ ããã¡ãªããã¨ãã¦ãæ¢åã®C/C++ã§å®è£ ãããããã°ã©ã (ã©ã¤ãã©ãª)ã¨ãªã³ã¯ãããããã¨ããäºãããã¨ãããã¾ãããã以å¤ã®ç®çã®å ´åãä¾ãã°Webãµã¼ãã¹ã¨ãã¦å®è£ ããå ´åã¯PHPãPerlãRubyãªã©ã®è¨èªã§å®è£ ããã¹ãã§ããããã¨ãã¹ã¿ã³ãã¢ãã³ããã°ã©ã ã§ããã¼ãããå®è£ ããå ´åã¯Cï¼ãJavaãªã©Twitterã®ãµãã¼ããåãè¨èªã§å®è£ ããæ¹ãè¯ãã¨ãããã¾ãã
åç½®ãã¯ãã®ãããã«ãã¦ãC/C++ã§XAuthã®ä»çµã¿ã«æ²¿ã£ã¦access-keyã®åå¾(èªã¿è¾¼ã¿ä¿åæ©æ§ä»ã)ãaccess-keyã使ã£ã¦Twitterã«æ¸ãè¾¼ãã§ã¿ãã¨ããããã°ã©ã ãæ¸ãã¦ã¿ããã¨æãã¾ãã
ã½ã¼ã¹ã³ã¼ãä¾
#include#include #include #include extern "C" { #include } // ã¢ããªã±ã¼ã·ã§ã³ã§ä½¿ç¨ããXAuthã¢ã¯ã»ã¹å¯è½ãªã³ã³ã·ã¥ãã¼ãã¼ãæå®ãã¦ãã ãã #define TWITTER_CONSUMER_KEY "" #define TWITTER_CONSUMER_SECRET "" int parse_reply(const char *reply, char **token, char **secret) { int rc; int ok = 1; char **rv = NULL; rc = oauth_split_url_parameters(reply, &rv); qsort(rv, rc, sizeof(char *), oauth_cmpstringp); int oauth_cnt = 0; for (int i = 0; i < rc; i++) { if (strncmp(rv[i], "oauth_token_secret=", 18) == 0) { if (secret) { *secret = strdup(&(rv[i][19])); oauth_cnt++; } } else if (strncmp(rv[i], "oauth_token=", 11) == 0) { if (token) { *token = strdup(&(rv[i][12])); oauth_cnt++; } } } if (rv) { free(rv); } if (oauth_cnt >= 2) { ok = 0; } else { ok = 1; free(*token); *token = NULL; free(*secret); *secret = NULL; } return ok; } int twitter_xauth_getaccesskey(char **token, char **secret, const char *username, const char *password) { const char *access_token_uri = "https://api.twitter.com/oauth/access_token"; char *req_url = NULL; char *postarg = NULL; char *reply = NULL; int argc = 4; char argv_wark[512]; char **argv = (char**) malloc(sizeof(char*) * 4); argv[0] = strdup(access_token_uri); argv[1] = strdup("x_auth_mode=client_auth"); snprintf(argv_wark, sizeof(argv_wark), "x_auth_password=%s", password); argv[2] = strdup(argv_wark); snprintf(argv_wark, sizeof(argv_wark), "x_auth_username=%s", username); argv[3] = strdup(argv_wark); req_url = oauth_sign_array2(&argc, &argv, &postarg, OA_HMAC, NULL, TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET, NULL, NULL); free(argv[3]); free(argv[2]); free(argv[1]); free(argv[0]); free(argv); reply = oauth_http_post(req_url, postarg); if (req_url) free(req_url); if (postarg) free(postarg); if (!reply) return 3; if (parse_reply(reply, token, secret)) return 4; free(reply); return 0; } int twitter_status_write(const char *token, const char *secret, const char *str) { const char *test_call_uri = "http://api.twitter.com/1/statuses/update.json"; char *req_url = NULL; char *postarg = NULL; char *reply = NULL; int argc = 2; char argv_wark[512]; char **argv = (char**) malloc(sizeof(char*) * 2); argv[0] = strdup(test_call_uri); snprintf(argv_wark, sizeof(argv_wark), "status=%s", str); argv[1] = strdup(argv_wark); req_url = oauth_sign_array2(&argc, &argv, &postarg, OA_HMAC, NULL, TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET, token, secret); free(argv[1]); free(argv[0]); free(argv); reply = oauth_http_post(req_url, postarg); printf("req_url:'%s'\n", req_url); printf("postarg:'%s'\n", postarg); printf("reply:'%s'\n", reply); if (req_url) free(req_url); if (postarg) free(postarg); if (reply) free(reply); return (0); } int twitter_load_key(const char *file, char **token, char **secret) { char work[256]; int i; FILE *fp = fopen(file, "r"); if (fp == NULL) return -1; fgets(work, sizeof(work), fp); for(i=0; i
åä½ã«å¿ è¦ãªãã®
ããã°ã©ã å 容ã®èª¬æã«é¢ãã¦ã¯å²æãã¾ãããã®ããã°ã©ã ãåä½ãããã«ã¯Twitter-devã§ããã°ã©ã ãç»é²ããã¢ããªã±ã¼ã·ã§ã³ãã¼ãåå¾ããå¿ è¦ãããã¾ããã¢ããªç»é²å¾ã«åå¾ããCONSUMER_KEYã¨TWITTER_CONSUMER_SECRETãä¸è¨ã½ã¼ã¹ã³ã¼ãã®å®æ°ã¨ãã¦è¨å®ããã¾ããOAuthã使ãã ããªããã®æç¹ã§åä½ãããããããã«ãªãã¾ãããXAuthã使ãå ´åã¯ãããã«ã¡ã¼ã«(api@twitter.com)ã«ã¦XAuthã®å®è¡è¨±å¯ããããå¿ è¦ãããã¾ããXAuth権éãããã£ã¦ããªãç¶æ ã ã¨access-keyåå¾ã®ããã«å®è¡ããPOSTã¡ã½ããã«å¤±æãã¾ããテンプレãåèã«ã¡ã¼ã«ãåºããXAuth権éãä»ä¸ããã段éã§ä¸è¨ããã°ã©ã ãåä½ããããã«ãªãã¾ãã(大ä½ï¼ãï¼æ¥ã§æ¨©éãä»ä¸ããã¾ã)