このプログラムは、「利用者ごとにFrogNoteのバックアップデータを永続化する」ためのAPIサーバです。 実際に運営するサービスではないため、全ソースを公開しています。 サーバ開発の勉強用のため、エラーハンドリングなどは雑におこなっています。
現状、サーバ側ではユースケースを定義していないからです。ユースケースはクライアント側で設定できるようにした方が、利用しやすいAPIになると思ったからです。 そのため、サーバ側では基本的なCRUD操作や、認証の仕組みだけを提供しています。
現状、UIにあたる処理がHandlerだけかつ、GUIと違ってUIに関する複雑な処理はないため、Infrastructure層内部に実装しています。
Entry層ではアプリケーションの起動処理(一度だけ行う処理)を行います。
そのため、非常に薄いレイヤとなっています。
具体的には、Server
構造体の変数にハンドラを設定して起動しています。
この層が実際の処理を担当する層となっています。 大きく三つのモジュール群に分けられます。
servers
security
db
このモジュールには、サーバ本体、ハンドラ、ロガーが含まれ、HTTPリクエストを受信するのが目的となっています。
このモジュールは、パスワードのハッシュ化、アクセストークンの管理など、セキュリティインフラを担っています。
このモジュールはMySQLにアクセスし、ドメインモデルを永続化・復元します。
現状この層はドメインモデルを表現するための層になっています。「利用者ごとにFrogNoteのバックアップデータを永続化する」という目的なので、今回の場合、「ユーザ」、「バックアップ」がドメインモデルにあたります。
SQL文の組み立ては単純な文字列置換を行わず、プレースホルダを用いています。
現状HTTPでサーブしています。GitHubに公開することを考えると証明書までプッシュしないといけなくなるからです。 HTTP通信では通信が暗号化されていなかったり、証明が行えない問題はありますが、今回は扱わないものとしています。
パスワードは必要最低限の処理をしてからデータベースに格納しています。 具体的には、SHA-256で10,000回ハッシュ化してから格納しています。もし、これ以上の対策を行うとすれば、ハッシュ化時にSaltやPaperを用いるとさらに堅牢になります。
セッション用のIDをサインイン時に発行し、通信しています。セッションIDはuuidを用いているので推測が困難です。 また、セッションIDは、サーバ内部の辞書(map)でユーザIDと紐づけて管理しています。
クライアント側がサインアウトしたことを通知した際に破棄するようにしています。実際に運用する場合は、時間経過で破棄することも必要になると思います。
AuthorizationヘッダのセッションIDが存在するかで認証済みか認証されていないかを判定しています。 そのため、セッションIDが盗まれると乗っ取りが可能な仕組みです。
サインインする際は、ユーザからサインインID、パスワードが送信されます。 パスワードは平文が送られるので、一度ハッシュ化してからデータベース内のパスワードと比較しています。 リプレイ攻撃の対策はしていないので、チャレンジ&レスポンス認証に切り替えることを検討する必要があります。