Titanium MobileでDigest認証を使ってHTTP接続する
Titanium MobileでHTTPのDigest認証するためのコードのサンプルです。
簡単にコピペできるようにあえて、モジュール化もしていません。
ソース自身は、githubのhttpclient-digest.nodeを参照して、一部改変しました。
function sampleDigestAuth() { var xhr = Ti.Network.createHTTPClient(); xhr.onload = function() { Ti.API.info("status:" + this.status); if (this.status == 200) { Ti.API.info("responseText:" + this.responseText); Ti.API.info("Content-Type:" + this.getResponseHeader("Content-Type")); } } xhr.onerror = function() { Ti.API.info("status:" + this.status); if (this.status == 401) { var wwwAuth = xhr.getResponseHeader('WWW-Authenticate'); Ti.API.info("auth:" + wwwAuth); var authInfo = parseWWWAuth(wwwAuth); var user = "foo"; var password = "password"; var authorization = createAuthHeader("GET", authInfo.realm, authInfo.nonce, authInfo.opaque, authInfo.qop, user, password, "/"); //Ti.API.info("h:" + h); xhr.open('GET', 'http://localhost:8124/'); xhr.setRequestHeader("Authorization", authorization); xhr.send(); } } xhr.open('GET', 'http://192.168.11.103:8124/'); xhr.send(); } function parseWWWAuth(wwwAuth) { var ret = {}; ret['realm'] = wwwAuth.match(/realm="([^"]+)"/)[1]; ret['qop'] = wwwAuth.match(/qop="([^"]+)"/)[1]; ret['nonce'] = wwwAuth.match(/nonce="([^"]+)"/)[1]; var opaqueMatch = wwwAuth.match(/opaque="([^"]+)"/); if (opaqueMatch) ret['opaque'] = opaqueMatch[0]; return ret; } function createAuthHeader(method, realm, nonce, opaque, qop, username, password, uri) { var a1 = buildA1(realm, username, password) var ha1 = Titanium.Utils.md5HexDigest(a1) var a2 = buildA2(method, uri) var ha2 = Titanium.Utils.md5HexDigest(a2) var nc = formatNonceCount(1) var cnonce = buildCnonce(); var response = buildResponse(ha1, ha2, nonce, nc, cnonce, qop) var hresp = Titanium.Utils.md5HexDigest(response) var ret = buildAuthHeader(username, realm, nonce, uri, cnonce, nc, qop, hresp, opaque); return ret; } // create client cnonce function buildCnonce() { return random(12, "0123456789abcdef"); } function random(len, source) { var result = ''; var sourceLen = source.length; for (var i = 0; i < len; i++) { result += source.charAt(Math.floor(Math.random() * sourceLen)); } return result; } function buildResponse(ha1, ha2, nonce, nc, cnonce, qop) { return ha1 + ":" + nonce + ":" + nc + ":" + qop + ":" + ha2 } function buildAuthHeader(username, realm, nonce, uri, cnonce, nc, qop, hresp, opaque) { var ret = 'Digest username="' + username + '", realm="' + realm + '", nonce="' + nonce + '", uri="' + uri + '", nc=' + nc + ', qop="' + qop + '", response="' + hresp + '", cnonce="' + cnonce + '"' '", algorithm="' + "MD5" + '"'; return ret; } function formatNonceCount(count) { var nc = count.toString(16); while(nc.length < 8) { nc = "0" + nc; } return nc } function buildA1(realm, user, passwd) { return user + ":" + realm + ":" + passwd } function buildA2(method, uri) { return method + ":" + uri }
参照