APIの認証方法

APIの認証方法

API の認証方法

JSON API メソッドのほとんどが認証を必要とします。このルールの唯一の例外は、認証を必要としない /public/ が前についたパス配下のメソッドです。認証は承認をするための前提条件です。例えば、実際の呼び出し先は要求されたデータにアクセスするために必要とされるパーミッションを持っていることで確認できます。

このページは、認証のメカニズムの技術的な詳細を記載しています。また、それらを複数のプログラム言語での使用する方法についても記載しています。"cx.py" ユーティリティによるコマンドラインからのAPIの使用方法について知りたい場合には、スタートガイドをご覧ください。

HTTPヘッダ

認証は、HTTPヘッダーにX-cXense-Authenticationを入れてリクエスト実行します。このヘッダーは、ユーザー名と日付とHMAC SHA256シグネチャを含みます。日付のパラメーターは、リクエストが短時間のみ有効とするために使用されます。このため、クライアント側は正確な時刻・タイムゾーンを利用する事が必要です。代替として、クライアントは認証の必要がない /public/date APIメソッドを用いて現在時刻を取得し、その値を利用することも可能です。
X-cXense-Authenticationヘッダーのフォーマットは以下の通りです:
username=<username> date=<date> hmac-sha256-<encoding>=<signature>
プレースホルダーの値は以下の通りです:

内容

<username>

https://insight.cxense.com に登録しているメールアドレスです。

<date>

現在の日時(ISO8601形式に準拠してください)

<encoding>

<signature>のエンコード方式。hexかbase64が利用可能です。

<signature>

エンコードされたHMAC SHA256シグネチャ、<date>、APIキーと対になる<username>を含めます

APIキーの確認は、https://insight.cxense.com にログイン後、画面の右上のユーザー名をクリックするとポップアップされます。 が、APIキーの参照権限を持つ方のみがこれを確認可能です。詳しくは APIキー確認方法 をご覧ください。

Persisted リクエストについて

公開済みWebページ上でウィジェットに使用するための永続的な認証されたリクエストがサポートされています。そのリクエストは認証されたユーザーがパスとリクエストパラメータを付与することで作成されます。認証されていないユーザーは永続的なリクエスト識別子を付与することによって、こうしたリクエストを実行できます。リクエストは作成したユーザーの証明書を使って実行し、実行者が何らかの修正をすることはできません。これにより格納された証明書を使って追加のデータを照会できるという恐れはなく、Webサイト上に有効なデータのサブセットを表示することができます。リクエストの識別子は作成者だけに知られている大きなランダムな文字列であるため、作成者によって識別子を与えられた人だけが実行できます。また権限のある方のみが作成可能です。
どのように永続的なリクエストを作成、実行するか、またその権限については /persisted/create をご確認ください。

Pythonでの作成例

以下は、PythonでのAPI認証のコード例です。

#!/usr/bin/python import datetime import hashlib import hmac import httplib import json def cx_api(path, obj, username, secret): body = json.dumps(obj) date = datetime.datetime.utcnow().isoformat() + "Z" signature = hmac.new(secret, date, digestmod=hashlib.sha256).hexdigest() headers = {"X-cXense-Authentication": "username=%s date=%s hmac-sha256-hex=%s" % (username, date, signature)} headers["Content-Type"] = "application/json; charset=utf-8" connection = httplib.HTTPSConnection("api.cxense.com", 443) connection.request("POST", path, json.dumps(obj), headers) response = connection.getresponse() return response.status, json.load(response) if __name__ == "__main__": username = "CxenseのユーザーID" secret = "ユーザーIDに紐づくAPIキー" print(cx_api("/site", {"siteId": "サイトIDを指定"}, username, secret))
#!/usr/bin/python import datetime import hashlib import hmac import http.client import json def cx_api(path, obj, username, secret): date = datetime.datetime.utcnow().isoformat() + "Z" signature = hmac.new(secret.encode('utf-8'), date.encode('utf-8'), digestmod=hashlib.sha256).hexdigest() headers = {"X-cXense-Authentication": "username=%s date=%s hmac-sha256-hex=%s" % (username, date, signature)} headers["Content-Type"] = "application/json; charset=utf-8" connection = http.client.HTTPSConnection("api.cxense.com", 443) connection.request("POST", path, json.dumps(obj), headers) response = connection.getresponse() status = response.status responseObj = json.loads(response.read().decode('utf-8')) connection.close() return status, responseObj if __name__ == "__main__": username = "CxenseのユーザーID" secret = "ユーザーIDに紐づくAPIキー" print(cx_api("/site", {"siteId": "サイトIDを指定"}, username, secret))

Javaでの作成例

以下は、JAVAでのAPI認証のコード例です。 例は、ヘッダーの設定をサポートするgetAuthenticationHeader()メソッドを含んでいます。mainメソッドにjava.net.URLConnectionを使った記述が含まれています。

import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.util.Formatter; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.joda.time.format.ISODateTimeFormat; public class AuthenticationExample { public static String getAuthenticationHeader(String username, String secret) throws Exception { Mac mac = Mac.getInstance("HmacSHA256"); mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256")); String date = ISODateTimeFormat.dateTime().print(new DateTime(DateTimeZone.UTC)); mac.update(date.getBytes("UTF-8")); byte[] signature = mac.doFinal(); Formatter hex = new Formatter(); for (byte b : signature) { hex.format("%02X", b); } return "username=" + username + " date=" + date + " hmac-sha256-hex=" + hex; } public static void main(String[] args) throws Exception{ URLConnection connection = new URL("https://api.cxense.com/site?json=%7B%7D").openConnection(); connection.setRequestProperty("X-cXense-Authentication", getAuthenticationHeader("YOUR USER NAME", "YOUR API KEY")); connection.connect(); BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); System.err.println(reader.readLine()); } }

C# での作成例

以下は、C#でのAPI認証のコード例です。アプリケーションは特定のサイトについての情報を返します。

using System; using System.IO; using System.Linq; using System.Net; using System.Security.Cryptography; using System.Text; namespace Cxense { class Program { static void Main(string[] args) { string user = "CxenseのユーザーID"; string apiKey = "ユーザーIDに紐づくAPIキー"; string siteId = "サイトID"; string apiUrl = "https://api.cxense.com/site"; var date = DateTime.UtcNow.ToString("o"); var hmacsha256 = new HMACSHA256(Encoding.UTF8.GetBytes(apiKey)); var hmac = hmacsha256.ComputeHash(Encoding.UTF8.GetBytes(date)); var hmacHex = hmac.Aggregate(new StringBuilder(32), (sb, b) => sb.Append(b.ToString("X2"))).ToString(); WebRequest request = WebRequest.Create(apiUrl); request.ContentType = "application/json"; request.Headers.Add("X-cXense-Authentication", "username=" + user + " date=" + date + " hmac-sha256-hex=" + hmacHex); request.Method = "POST"; string query = "{\"siteId\":\"" + siteId + "\"}"; byte[] byteArray = Encoding.UTF8.GetBytes(query); request.ContentLength = byteArray.Length; try { Stream dataStream = request.GetRequestStream(); dataStream.Write(byteArray, 0, byteArray.Length); dataStream.Close(); WebResponse response = request.GetResponse(); using (var reader = new StreamReader(response.GetResponseStream())) { string result = reader.ReadToEnd(); reader.Close(); Console.WriteLine(result); } response.Close(); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } Console.ReadKey(); } } }

Node.js での作成例

以下は、node.jsでのAPI認証のコード例です。

var request = require('request'), crypto = require('crypto'); var username = 'username', apiKey = 'apiKey'; var date = new Date().toISOString(), hmac = crypto.createHmac('sha256', apiKey).update(date).digest('hex'); request.post({ url: 'https://api.cxense.com/traffic/event', headers: { 'X-cXense-Authentication': 'username=' + username + ' date=' + date + ' hmac-sha256-hex=' + hmac }, body: { 'start': -3600, 'siteId': '1234567890' }, json: true }, function (error, response, body) { if (!error && response.statusCode === 200) { console.log('The event group count: ' + body.groups.length); } });

Google App Script example

/* HELPER FUNCTION */ function hexdigest(bytearray) { // howto convert bytearray to hexstring // http://stackoverflow.com/a/34111253/1104502 return bytearray.map(function(b) {return ("0" + (b < 0 && b + 256 || b).toString(16)).substr(-2)}).join("") } var username = 'username', apiKey = 'apiKey'; var date = new Date().toISOString(); var hmac = hexdigest(Utilities.computeHmacSha256Signature(date, apiKey)); var payload = { start: -3600, siteId: '1234567890' }; var url = 'https://api.cxense.com/traffic/event'; var params = { // don't mute HTTP exceptions 'muteHttpExceptions': false, 'method': 'post', 'contentType': 'application/json', 'headers': { 'X-cXense-Authentication': 'username=' + username + ' date=' + date + ' hmac-sha256-hex=' + hmac }, // Convert the JavaScript object to a JSON string. 'payload': JSON.stringify(payload), }; var response = UrlFetchApp.fetch(url, params); // get status and data from HTTPResponse objec

PHPでの作成例

以下は、PHPでのAPI認証のコード例です。記述例のコード、hash_hmac機能を使用するためPHPバージョン5.1.2以上で動作します。 テストのためのデバッグ出力の2つのブロックがあります。

<?php echo 'Current PHP version: ' . phpversion() . "<br>"; $username="CxenseのユーザーID"; $apikey="ユーザーIDに紐づくAPIキー"; $date = date("Y-m-d\TH:i:s.000O"); $signature=hash_hmac("sha256", $date, $apikey); echo "date: $date <br>"; echo "signature: $signature <br>"; echo "username: $username <br>"; echo "apikey: $apikey <br>"; $url = 'https://api.cxense.com/traffic/event'; $plainjson_payload = "{\"start\":-3600, \"siteId\":\"サイトID\"}"; echo "plainjson_payload: $plainjson_payload <br>"; echo "X-cXense-Authentication: username=$username date=$date hmac-sha256-hex=$signature\r\n"; $options = array( 'http' => array( 'header' => "Content-Type: application/json; charset=UTF-8\r\n". "X-cXense-Authentication: username=$username date=$date hmac-sha256-hex=$signature\r\n", 'method' => 'POST', 'content' => $plainjson_payload, ), ); $context = stream_context_create($options); $result = file_get_contents($url, false, $context); var_dump($result); ?>

Perlでの作成例

以下は、PerlでのAPI認証のコード例です。


Expand source
#!/usr/bin/perl -w
use LWP;
use strict;
use warnings;
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0;
use REST::Client;
use Digest::SHA qw(hmac_sha256_hex);
use Datetime;
use Data::Dumper;
my $browser = LWP::UserAgent->new;
my $username = 'CxenseユーザーID';
my $apikey = 'ユーザーIDに紐づくAPIキー';
my $SITEID = 'サイトID';
my $dt = DateTime->now();
$dt .= '.000000Z';
my $digest = hmac_sha256_hex($dt,$apikey);
my $p_json_payload = "{\"start\":-3600, \"siteId\":\"$SITEID\"}";
my $restUrl = 'https://api.cxense.com/traffic/event';
my $headers = {
'Content-Type' => 'application/json',
'Accept' => 'application/json', 'X-cXense-Authentication' => "username=$username date=$dt hmac-sha256-hex=$digest"
};
my $restClient = REST::Client->new();
$restClient->request('POST', "$restUrl", "$p_json_payload", $headers);
print $restClient->responseContent();

#!/usr/bin/perl -w use LWP; use strict; use warnings; $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0; use REST::Client; use Digest::SHA qw(hmac_sha256_hex); use Datetime; use Data::Dumper; my $browser = LWP::UserAgent->new; my $username = 'CxenseユーザーID'; my $apikey = 'ユーザーIDに紐づくAPIキー'; my $SITEID = 'サイトID'; my $dt = DateTime->now(); $dt .= '.000000Z'; my $digest = hmac_sha256_hex($dt,$apikey); my $p_json_payload = "{\"start\":-3600, \"siteId\":\"$SITEID\"}"; my $restUrl = 'https://api.cxense.com/traffic/event'; my $headers = { 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'X-cXense-Authentication' => "username=$username date=$dt hmac-sha256-hex=$digest" }; my $restClient = REST::Client->new(); $restClient->request('POST', "$restUrl", "$p_json_payload", $headers); print $restClient->responseContent();

Rubyでの作成例

以下は、RubyでのAPI認証のコード例です。

#!/usr/bin/ruby -w require "rubygems" require "rest-client" require "openssl" digest = OpenSSL::Digest::SHA256.new secret = "ユーザーIDに紐づくAPIキー" uname = "CxenseユーザーID" siteid = "サイトID" resturl = "https://api.cxense.com/traffic/event" payload = "{\"start\":-3600, \"siteId\":\"" + siteid + "\"}" timetoseed = Time.now.utc string_to_sign = timetoseed.strftime("%FT%R") + ":02.000000Z" signature = OpenSSL::HMAC.hexdigest(digest, secret, string_to_sign) auth_header = "username=" + uname + " date=" + string_to_sign + " hmac-sha256-hex=" + signature response = RestClient.post(resturl, payload, :content_type => :json, :accept => :json, :'X-cXense-Authentication' => auth_header) puts response.code puts response.body

 

Swift example

以下は、Swift 3でのAPI認証のコード例です。

import Alamofire import CryptoSwift ... func AuthenticationHeaderString(for username: String, and apiKey: String) -> String { let df = DateFormatter() df.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ" let currentDate = df.string(from: Date()) let pwd = try! HMAC(key: apiKey, variant: .sha256).authenticate("\(currentDate)".utf8.map {$0}) return "username=\(username) date=\(currentDate) hmac-sha256-base64=\(pwd.toBase64()!)" } ... let userName = "CxenseユーザーID" let apiKey = "ユーザーIDに紐づくAPIキー" let headers: HTTPHeaders = [ "Accept" : "application/json", "Content-Type" : "application/json", "X-cXense-Authentication": AuthenticationHeaderString(for: userName, and: apiKey) ] Alamofire.request("https://api.cxense.com/profile/user", method: .post, parameters: ["id":"123456789","type":"cx"], encoding: JSONEncoding.default, headers: headers).responseJSON { (response) in print("JSON Response: \(response)") }