SESAMEのAPIはすばらしいけど、、、
sesame miniを買ったのです。そしてSESAMEのBlog( https://ameblo.jp/candyhouse-inc/entry-12413908790.html )で紹介されていたラズパイ&SUICAの組合せで動かしていました。こいつは素晴らしい。玄関先にNFCリーダつけたラズパイをおいておけば、スマホのアプリを起動する手間すらいらない。iphoneをピットかざすだけでスイカを読み取って鍵があきます。
ただ、ある日気づいたんです。これ、いろいろ大切な情報が平文で入ってますよね、、、
ちょっとでもセキュアに
セキュリティはもう奥が深すぎて僕にはとても手が及ばないです。
せめて外においているラズパイに大切な情報が平文ってのだけどうにかしよう。ということで考えたのが以下。我が家には室内にもnature remo代わりのラズパイが可動してるのでそいつを利用します。
RESTを使ってみたかった
今回RasberryPi間の情報のやりとりはRESTを使ってみました。SESAMEのAPIもRESTですし、僕自身仕事でRESTREST連呼してるので使ったかったんです。
参考にしたのはこちら
https://qiita.com/Morinikiz/items/c2af4ffa180856d1bf30
さてプログラミング
今回は2台のラズパイにそれぞれサーバのプログラムとクライアントのプログラムが必要になります。
ラズパイ宅内側
RESTとSESAME Blogをがっちゃんこです。
SUICAのIdmが一致しなかった場合は404、ここは適当アタックを避けるために遅延を入れたほうがいいのかも。
# -*- coding: utf-8 -*-
from flask import Flask, jsonify, abort, make_response
import requests
import json
# login CANDY HOUSE account and get token
url = "https://api.candyhouse.co/v1/accounts/login"
head = {"Content-type": "application/json"}
payload = {"email":"a@bcd.com", "password":"abcd"}
response = requests.post(url, headers=head, data=json.dumps(payload))
token = response.json()["authorization"]
api = Flask(__name__)
@api.route('/getIdm/<string:userId>', methods=['GET'])
def get_idm(userId):
if (userId == "0139XXXXXXXXXXXX") or (userId == "0139XXXXXXXXXXXX"):
result = 'OK' + userId
print result
# unlock Sesame with token
url_control = "https://api.candyhouse.co/v1/sesames/XXXXXXXXXXX/control"
head_control = {"X-Authorization": token, "Content-type": "application/json"}
payload_control = {"type":"unlock"}
response_control = requests.post(url_control, headers=head_control, data=json.dumps(payload_control))
else :
abort(404)
return make_response(jsonify(result))
@api.errorhandler(404)
def not_found(error):
return make_response(jsonify({'error': 'Not found'}), 404)
if __name__ == '__main__':
api.run(host='192.168.XXX.XXX', port=XXXX)
Linux系ならCURL使えば簡単にデバックできます。さすがREST。
curl -i http://192.168.XXX.XXX:XXXX/getIdm/YYYYYY
ラズパイ玄関外
先程のsesameBlogを元にラズパイをnfc認識するように設定してください
https://ameblo.jp/candyhouse-inc/entry-12413908790.html
そんでブログのページのコードを改造
# -*- coding: utf-8 -*-
import requests
import binascii
import nfc
import time
from threading import Thread, Timer
# Suica待ち受けの1サイクル秒
TIME_cycle = 1.0
# Suica待ち受けの反応インターバル秒
TIME_interval = 0.2
# タッチされてから次の待ち受けを開始するまで無効化する秒
TIME_wait = 3
# NFC接続リクエストのための準備
# 212F(FeliCa)で設定
target_req_suica = nfc.clf.RemoteTarget("212F")
# 0003(Suica)
target_req_suica.sensf_req = bytearray.fromhex("0000030000")
print 'Waiting for SUICA...'
while True:
# USBに接続されたNFCリーダに接続してインスタンス化
clf = nfc.ContactlessFrontend('usb')
# Suica待ち受け開始
# clf.sense( [リモートターゲット], [検索回数], [検索の間隔] )
target_res = clf.sense(target_req_suica, iterations=int(TIME_cycle//TIME_interval)+1 , interval=TIME_interval)
if target_res != None:
tag = nfc.tag.activate_tt3(clf, target_res)
tag.sys = 3
#IDmを取り出す
idm = binascii.hexlify(tag.idm)
#REST用のurlを生成
url = "http://192.168.XXX.XXX:XXXX/getIdm/" + idm
response = requests.get(url)
print(response.text)
print 'sleep ' + str(TIME_wait) + ' seconds'
time.sleep(TIME_wait)
#end if
clf.close()
# end while
これから
文中でもちらと書きましたがこのままではidmはしから試されかねないので、idmが不正だったときに遅延させる仕組みとか、宅外のラズパイのステータスをLEDで表示したりとかさせたいです。