前提・実現したいこと
Javaで家計簿サイトZAIMのAPIをコールして、家計簿情報を取得・登録するアプリを開発したいとトライしているのですが、
リクエストトークンを取得する際にエラーになっている(?)と思われるところで詰まっています。
初歩的な問題かもしれませんが、助言宜しくお願い致します。
発生している問題・エラーメッセージ
Exception in thread "main" java.io.IOException: Server returned HTTP response code: 400 for URL: https://api.zaim.net/v2/auth/request at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1838) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1439) at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254) at myapp.main(TestZaim.java:87)
該当のソースコード
Java
1//ネット上で有識者が公開して下さっていたソースコードを流用しております。 2import java.io.BufferedReader; 3import java.io.InputStreamReader; 4import java.io.UnsupportedEncodingException; 5import java.net.HttpURLConnection; 6import java.net.URL; 7import java.net.URLEncoder; 8import java.util.Map.Entry; 9import java.util.SortedMap; 10import java.util.TreeMap; 11import javax.crypto.Mac; 12import javax.crypto.spec.SecretKeySpec; 13import sun.misc.BASE64Encoder; 14 15public class TestZaim { 16 17 public static void main(String[] args) throws Exception { 18 // OAuthにおいて利用する変数宣言 19 String consumerkey = "略"; 20 String consumerSecret = "略"; 21 String oauthToken = ""; // リクエストトークン取得時は利用しない 22 String oauthTokenSecret = ""; // リクエストトークン取得時は利用しない 23 String method = "POST"; 24 String urlStr = "https://api.zaim.net/v2/auth/request"; 25 26 // OAuthにおいて利用する共通パラメーター 27 // パラメーターはソートする必要があるためSortedMapを利用 28 SortedMap<String, String> params = new TreeMap<String, String>(); 29 params.put("oauth_consumer_key", consumerkey); 30 params.put("oauth_signature_method", "HMAC-SHA1"); 31 params.put("oauth_timestamp", String.valueOf(getUnixTime())); 32 params.put("oauth_nonce", String.valueOf(Math.random())); 33 params.put("oauth_version", "1.0"); 34 // params.put("oauth_token", oauthToken); // リクエストトークン取得時は利用しない 35 36 { 37 /* 38 * 署名(oauth_signature)の生成 39 */ 40 // パラメーターを連結する 41 String paramStr = ""; 42 for (Entry<String, String> param : params.entrySet()) { 43 paramStr += "&" + param.getKey() + "=" + param.getValue(); 44 } 45 paramStr = paramStr.substring(1); 46 47 // 署名対象テキスト(signature base string)の作成 48 String text = method + "&" + urlEncode(urlStr) + "&" 49 + urlEncode(paramStr); 50 51 // 署名キーの作成 52 String key = urlEncode(consumerSecret) + "&" 53 + urlEncode(oauthTokenSecret); 54 55 // HMAC-SHA1で署名を生成 56 SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), 57 "HmacSHA1"); 58 Mac mac = Mac.getInstance(signingKey.getAlgorithm()); 59 mac.init(signingKey); 60 byte[] rawHmac = mac.doFinal(text.getBytes()); 61 String signature = new BASE64Encoder().encode(rawHmac); 62 63 // 署名をパラメータに追加 64 params.put("oauth_signature", signature); 65 } 66 67 // Authorizationヘッダの作成 68 String paramStr = ""; 69 for (Entry<String, String> param : params.entrySet()) { 70 paramStr += ", " + param.getKey() + "=\"" 71 + urlEncode(param.getValue()) + "\""; 72 } 73 paramStr = paramStr.substring(2); 74 String authorizationHeader = "OAuth " + paramStr; 75 76 // APIにアクセス 77 URL url = new URL(urlStr); 78 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 79 connection.setRequestMethod(method); 80 connection.setRequestProperty("Authorization", authorizationHeader); 81 connection.connect(); 82 BufferedReader reader = new BufferedReader(new InputStreamReader( 83 connection.getInputStream())); 84 String response; 85 while ((response = reader.readLine()) != null) { 86 System.out.println(response); 87 } 88 } 89 90 private static int getUnixTime() { 91 return (int) (System.currentTimeMillis() / 1000L); 92 } 93 94 private static String urlEncode(String string) { 95 try { 96 return URLEncoder.encode(string, "UTF-8"); 97 } catch (UnsupportedEncodingException e) { 98 throw new RuntimeException(e); 99 } 100 }
試したこと
ZAIMへアプリ申請し、consumerKey,consumerSecretを取得。
リクエストトークン取得URL:https://api.zaim.net/v2/auth/request
ローカル環境よりeclispe上でJunitテストを実施し、上記エラーが発生。
補足情報(FW/ツールのバージョンなど)
Java1.6 + Junit
eclipse4.4
★20180311追記
ありがとうございます。Hurl.itにてPOST/oauth1.0aで試行してみましたので、その結果を記述します。
HEADERS
Connection: keep-alive
Content-Type: application/json; charset=utf-8
Date: Sun, 11 Mar 2018 04:36:13 GMT
Server: nginx
Transfer-Encoding: chunked
X-Powered-By: PHP/7.1.13-1+ubuntu16.04.1+deb.sury.org+1
BODY view raw
{
"error": true,
"message": "400 OAuth parameter(s) does not exist: oauth_callback"
}
TestZaim.java 87行目 connectionを実行する箇所です。
BufferedReader reader = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
★20180311追記
・呼び出し方事例(公式 https://oauth.net/core/1.0a/#anchor43)
After Jane informs printer.example.com that she would like to print her vacation photo stored at photos.example.net, the printer website tries to access the photo and receives HTTP 401 Unauthorized indicating it is private. The Service Provider includes the following header with the response:
WWW-Authenticate: OAuth realm="http://photos.example.net/"
The Consumer sends the following HTTP POST request to the Service Provider:
https://photos.example.net/request_token?oauth_consumer_key=dpf43f3p2l4k3l03&oauth_signature_method=PLAINTEXT&oauth_signature=kd94hf93k423kf44%26&oauth_timestamp=1191242090&oauth_nonce=hsu94j3884jdopsl&oauth_version=1.0&oauth_callback=http%3A%2F%2Fprinter.example.com%2Frequest_token_ready
The Service Provider checks the signature and replies with an unauthorized Request Token in the body of the HTTP response:
oauth_token=hh5s93j4hdidpola&oauth_token_secret=hdhd0244k9j7ao03&oauth_callback_confirmed=true
・phpコードサンプル(公式 https://dev.zaim.net/home/api/authorize)
<?php require_once('HTTP/OAuth/Consumer.php'); session_start(); // Provider info $provider_base = 'https://api.zaim.net/v2/auth/'; $request_url = $provider_base.'request'; $authorize_url = 'https://auth.zaim.net/users/auth'; $access_url = $provider_base.'access'; $resource_url = 'https://api.zaim.net/v2/home/user/verify'; // Consumer info $consumer_key = YOUR_CONSUMER_KEY; $consumer_secret = YOUR_CONSUMER_SECRET; $callback_url = sprintf('http://%s%s', $_SERVER['HTTP_HOST'], $_SERVER['SCRIPT_NAME']); // Session clear if (isset($_REQUEST['action']) && $_REQUEST['action'] === 'clear') { session_destroy(); $_SESSION = array(); session_start(); } $content = ''; try { // Initialize HTTP_OAuth_Consumer $oauth = new HTTP_OAuth_Consumer($consumer_key, $consumer_secret); // Enable SSL $http_request = new HTTP_Request2(); $http_request->setConfig('ssl_verify_peer', false); $consumer_request = new HTTP_OAuth_Consumer_Request; $consumer_request->accept($http_request); $oauth->accept($consumer_request); if (!isset($_SESSION['type'])) $_SESSION['type'] = null; // 2 Authorize if ($_SESSION['type']=='authorize' && isset($_GET['oauth_token'], $_GET['oauth_verifier'])) { // Exchange the Request Token for an Access Token $oauth->setToken($_SESSION['oauth_token']); $oauth->setTokenSecret($_SESSION['oauth_token_secret']); $oauth->getAccessToken($access_url, $_GET['oauth_verifier']); // Save an Access Token $_SESSION['type'] = 'access'; $_SESSION['oauth_token'] = $oauth->getToken(); $_SESSION['oauth_token_secret'] = $oauth->getTokenSecret(); } // 3 Access if ($_SESSION['type']=='access') { // Accessing Protected Resources $oauth->setToken($_SESSION['oauth_token']); $oauth->setTokenSecret($_SESSION['oauth_token_secret']); $result = $oauth->sendRequest($resource_url, array(), 'GET'); $content = $result->getBody(); // 1 Request } else { // Get a Request Token $oauth->getRequestToken($request_url, $callback_url); // Save a Request Token $_SESSION['type'] = 'authorize'; $_SESSION['oauth_token'] = $oauth->getToken(); $_SESSION['oauth_token_secret'] = $oauth->getTokenSecret(); // Get an Authorize URL $authorize_url = $oauth->getAuthorizeURL($authorize_url); $content = "Click the link.<br />\n"; $content .= sprintf('<a href="%s">%s</a>', $authorize_url, $authorize_url); } } catch (Exception $e) { $content .= $e->getMessage(); } ?> <html> <head> <title>OAuth in PHP</title> </head> <body> <h2>Welcome to a Zaim OAuth PHP example.</h2> <p><a href='?action=clear'>Clear sessions</a></p> <p><pre><?php print_r($content); ?><pre></p> </body> </html>回答1件
あなたの回答
tips
プレビュー