Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ServiceSyncとのつなぎ方 アプリ開発PubSub編

ServiceSyncとのつなぎ方 アプリ開発PubSub編

ServiceSyncとのつなぎ方
アプリ開発PubSub編

Daisuke Baba

June 19, 2014
Tweet

More Decks by Daisuke Baba

Other Decks in Technology

Transcript

  1. PubSubγʔέϯε Client Broker Event 1 Action 1 Event 2 Event

    3 User App Action 2 Subscribe Event 3 Subscribe σόΠε ΞϓϦ ServiceSync Ϣʔβʔ ΞϓϦ 3
  2. PubSubެ։ϙʔτ • ҉߸Խͳ͠TCP 1883 ʢඪ४MQTTϙʔτʣ • WebSockets 80 • WebSockets/SSL

    443 ΫϥΠΞϯτͷ छผʹΑͬͯ ར༻Ͱ͖Δϙʔτ ͕ҟͳΔ 4
  3. ϙʔτͷݖݶ؅ཧ • σόΠεɹ→ɹ୺຤ΞΧ΢ϯτ • ͢΂ͯͷެ։ϙʔτΛར༻Ͱ͖Δ • Ϣʔβʔɹ→ɹRESTͷϢʔβʔ୯Ґ • WebSocketsϙʔτͷΈར༻Ͱ͖Δ •

    ΞϓϦɹ→ɹSS಺෦Ͱ࣮ߦ͞ΕΔΞϓϦ • ඇެ։ϙʔτʢ಺෦ʣͷΈར༻Ͱ͖Δ • ݱ࣌఺Ͱ͸ະαϙʔτ 7
  4. τϐοΫACL ΞϓϦID ύοέʔδID Ϟσϧ໊ σόΠεॴଐυϝΠϯ σόΠεUUID σόΠε Ұൠ Ϣʔβʔ ΞϓϦ࡞੒

    Ϣʔβʔ ඞਢ ඞਢ ඞਢ ඞਢ ඞਢ ೚ҙ ඞਢ ඞਢ ೚ҙ ඞਢ ඞਢ ೚ҙ ඞਢ ೚ҙ ೚ҙ 11
  5. σόΠεొ࿥γʔέϯε REST Client ServiceSync Cloud POST /device AES256 (Device ID)

    HTTP 200 AES256 (new AES Key / Device UUID) PUT /device AES256 (JSON) HTTP 200 AES256 (JSON) Phase 1 Challenge Phase 2 Enrollment Using AES Key extracted from Enrollment Password Using AES Key returned at Phase 1 σόΠε ServiceSync ೝূɾ҉߸Խʹ࢖ ༻͢ΔAESΩʔ RESTͰ࣮ࢪ 15
  6. σόΠεೝূ • Client ID • dev:<σόΠε UUID>ͷจࣈྻ • Username •

    <Nonce਺஋>?<ΫΤϦʔจࣈྻ> • Password • HEX(HMAC-SHA1(<σόΠε UUID>:<Username>, <AES Key>)) 16
  7. Javaαϯϓϧ1/2 import org.fusesource.mqtt.client.Callback; import org.fusesource.mqtt.client.Future; import org.fusesource.mqtt.client.FutureConnection; import org.fusesource.mqtt.client.MQTT; import

    org.fusesource.mqtt.client.QoS; import org.fusesource.mqtt.client.Listener; import org.fusesource.mqtt.client.Topic; .... String deviceUid = "4028813a438a6e6c01438a76510d0307"; String aesKey = "ffffffffffffffffffffffffffffffff"; String clientId = "dev:" + deviceUid; String userName = String.valueOf(System.currentTimeMillis()) + "?c=Raw"; String nonceSeed = deviceUid + ":" + userName; String password = hmacsha1AsHexString(nonceSeed, aesKey); String eventTopic = "/" + applicationId + "/" + packageId + "/MyEvent" + domain + "/" + deviceUid; String actionTopic = "/" + applicationId + "/" + packageId + "/MyAction" + domain + "/" + deviceUid; MQTT mqtt = new MQTT(); mqtt.setHost("tcp://sandbox-ssmb.inventit.io:1883"); mqtt.setClientId(clientId); mqtt.setUserName(userName); mqtt.setPassword(password); final FutureConnection connection = mqtt.futureConnection(); connection.connect().then(new Callback<Void>() { @Override public void onSuccess(Void ignored) { // connected connection.subscribe( new Topic[] { new Topic(actionTopic, QoS.AT_MOST_ONCE) }, new Callback<byte[]>() { @Override public void onSuccess(byte[] value) { // byte data } @Override public void onFailure(Throwable t) { // failure } } ); connection.publish(eventTopic, "test".getBytes(), QoS.AT_MOST_ONCE, false); } @Override public void onFailure(Throwable t) { // failed to connect } }); •Fusesource͕ఏڙ͢ΔMQTTϥΠϒϥϦʔΛར༻ͨ͠ྫ •hmacsha1AsHexString(text,key)͸ɺ࣍εϥΠυʹهࡌ 20
  8. Javaαϯϓϧ2/2 import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.concurrent.TimeUnit; import javax.crypto.Mac; import

    javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Hex; ... public static String hmacsha1AsHexString(String nonceSeed, String aesKey) { try { SecretKeySpec sk = new SecretKeySpec(aesKey.getBytes(), "HmacSHA1"); Mac mac = Mac.getInstance("HmacSHA1"); mac.init(sk); byte[] digest = mac.doFinal(nonceSeed.getBytes()); return new String(Hex.encodeHex(digest)); } catch (InvalidKeyException e) { throw new IllegalArgumentException(e); } catch (NoSuchAlgorithmException e) { throw new IllegalArgumentException(e); } } • μΠδΣετܭࢉJavaϝιουྫ 21
  9. • μΠδΣετܭࢉϒϥ΢βʔJSྫ • JSFiddle • http://jsfiddle.net/HPm42/4/ ϒϥ΢βʔJSαϯϓϧ // Crypto JS

    from https://code.google.com/p/crypto-js/downloads/list <script src="hmac-sha1.js"></script> <script> var deviceUid = "4028813a438a6e6c01438a76510d0307"; var aesKey = "ffffffffffffffffffffffffffffffff"; var clientId = "dev:" + deviceUid; var userName = new Date().getTime() + "?c=MoatV1&e1=eeeb&f1=2a"; var nonceSeed = deviceUid + ":" + userName; var password = hmacsha1AsHexString(nonceSeed, aesKey); // connect to an MQTT broker... function hmacsha1AsHexString(nonceSeed, aesKey) { var key = CryptoJS.enc.Hex.parse(aesKey); var digest = CryptoJS.HmacSHA1(nonceSeed, key); return digest.toString(CryptoJS.enc.Hex); } </script> 22
  10. Password • RESTʹͯೝূΛ࣮ߦͨ࣌͠ʹɺSS͕ൃߦ͢ΔτʔΫϯจࣈྻ • Ұఆ࣌ؒޙʹ͸ແޮʹͳΔͨΊɺೝূΤϥʔ͕ग़ͨ৔߹͸ɺ࠶౓RESTʹͯ τʔΫϯΛऔಘ͠ͳ͚Ε͹ͳΒͳ͍ • ೝূηογϣϯΛ؅ཧ͢ΔͨΊRESTΛར༻͍ͯ͠Δ • curl

    "https://sandbox.service-sync.com/moat/v1/sys/auth?a=<ΞϓϦ ID>&u=<ΫϥΠΞϯτID>&c=<ΫϥΠΞϯτύεϫʔυ> => {"authUserId":"<ΫϥΠΞϯτID>", "accessToken":"...", "lastSignedIn":"...."} <ΞΫηετʔΫϯ> 27
  11. ϒϥ΢βʔJSαϯϓϧ • Hive MQʹͯެ։͍ͯ͠Δ΢Σϒϒϥ΢βʔΞϓ Ϧ • MQTT3.1.1޲͚ʹվ଄ͨ͠ϥΠϒϥϦʔΛར༻ • σόΠεΞΧ΢ϯτ΋ར༻Մೳ •

    ϩʔΧϧϑΝΠϧΛϒϥ΢βʔͰ։͍ͯར༻Մೳ • https://github.com/inventit/hivemq-mqtt-web- client 28
  12. Angular JSαϯϓϧ • Hive MQվ଄൛Ͱར༻ͨ͠MQTTϥΠϒϥ ϦʔΛ࢖༻ • RESTʹΑΔೝূτʔΫϯऔಘ΋࣮૷͞Ε ͍ͯΔ •

    https://github.com/inventit/moat-iot- sparki/blob/master/sparki-example-ionic/ www/js/ 29