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

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

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

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

Avatar for Daisuke Baba

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