$30 off During Our Annual Pro Sale. View Details »

2019-05 Webアプリケーション基礎知識/2019-05 Web application fundamentals

2019-05 Webアプリケーション基礎知識/2019-05 Web application fundamentals

Cybozu
PRO

May 29, 2019
Tweet

More Decks by Cybozu

Other Decks in Technology

Transcript

  1. Webアプリケーション基礎知識 2019 Yakumoチーム, Slash/CyDE-Cチーム 赤井駿平

  2. Introduction ▌Webアプリを作るのに必要な基礎知識を話します ⚫ 割りと雑多な知識 ⚫ 必要になった時にキーワードを思い出して自分で調べられ るように

  3. Webアプリケーションとはなんぞや ▌Webブラウザをインターフェースとして入出力するアプリ ケーション ⚫ 通信はHTTP、表示はHTML, CSS ▌実際のアプリはサーバーにある ▌≠ネイティブアプリ、デスクトップアプリ ⚫ 内部的にはWebアプリが提供するAPIを叩いている場合も

    ▌サイボウズが作っている製品はほとんどがWebアプリ
  4. Webサーバーは何をする?

  5. Webサーバー ▌HTTPを処理するサーバー ⚫ クライアントからリクエ ストを受け付けて ⚫ 所望の結果を返す ▌Apache, IIS, nginx...

    request: index.htmlください response: index.html どうぞ!
  6. Webサーバーがやること ▌リクエストを受け付ける ▌結果を(読み込む|計算する) ▌結果を送り返す ▌つまり、Input-Process-Output ⚫ InputとOutputはネットワークの処理 ⚫ This is

    “Program”
  7. Socket ▌サーバーとクライアントで通信するためのAPI ⚫ 主にTCP, UDP を使う ⚫ 同じマシン同士で通信しても、別のマシンと通信してもよ い

  8. Socket: クライアント側 ▌やること ⚫ 初期化 socket() ⚫ サーバーと接続 connect() ⚫

    送信 write() / 受信 read() ⚫ 終了 close() int sock = socket(AF_INET, SOCK_STREAM, 0); connect(sock, アドレス, len); write(sock, buf, buflen); read(sock, buf, buflen); close(sock);
  9. Socket: サーバー側 ▌やること ⚫ socket() ⚫ アドレスを設定 bind() ⚫ リクエスト受付

    listen() ⚫ リクエストを確立 accept() ⚫ read()/write() ⚫ close() int sock = socket(AF_INET, SOCK_STREAM, 0); bind(sock, アドレス, len); listen(sock, 128); while(1) { int fd = accept(sock, NULL, NULL); write(fd, buf, buflen); read(fd, buf, buflen); close(fd); } close(sock);
  10. 複数のリクエストが来たら ▌サーバーが1つのリクエストを処理している時に別のリクエス トが来る ⚫ 前のページのコードだとどうなる?

  11. 同時に複数のリクエストを捌く ▌リクエストの待受とリクエストの処理を同時に行えると良い ⚫ acceptが返ったら処理を開始 ⚫ 処理の結果を待たずに、すぐにacceptに戻る ▌プロセスやスレッドを使う while(1) { int

    fd = accept(sock, NULL, NULL); 処理開始(fd); //すぐに返ってくる }
  12. プロセス ▌プログラムの実行の単位 ⚫ コマンドやアプリを起動するとプロセスが立ち上がる ⚫ 別のプロセスのメモリにはアクセスできない ⚫ 異なるプロセスは並列に動くことができる ▌Webサーバーでは ⚫

    リクエストを受付 ⚫ 処理プロセスを起動してソケットを引き継ぐ
  13. スレッド ▌1つのプロセスの中の処理の単位 ⚫ プロセスより軽い ⚫ 並列に実行可能 ⚫ 同じプロセスの別のスレッドのメモリにアクセスできる ▌Webサーバーでは ⚫

    リクエストを受付 ⚫ 処理スレッドを起動して処理をする
  14. Webアプリケーション

  15. 動的なWebページ ▌Webは静的なページを返すだけじゃない ⚫ Input-Process-Output (= プログラム) ⚫“Process” で任意のプログラムを実行して結果を返す ⚫ サイボウズOfficeもGaroonもkintoneもメールワイズもこの

    タイプ ▌処理の仕方はいろいろある
  16. CGI: Common Gateway Interface ▌Webサーバーとプログラムがやりとりするためのインターフェース ⚫ リクエストが来るたびにアプリのプロセスを起動する ⚫ リクエストの内容は、環境変数や標準入力で渡される ⚫

    結果は標準出力で返す ▌昔はこのやり方が主流 ⚫ Perlの時代 ⚫ 毎回プロセスを起動するので遅い ⚫ サイボウズ Office / メールワイズは今でもこれ request response program stdin/env stdout
  17. Webアプリケーションサーバー ▌Webアプリケーションを実行するサーバー ⚫ CGIと異なり、通常起動しっぱなし ⚫ Webサーバーがアプリケーションサーバーにリクエストを 中継する ⚫主にHTTPでやりとり ⚫ アプリケーションサーバーとアプリの間

    ⚫特定のメソッドを呼んだりしてやりとり request response App server request response App
  18. 永続化/データベース ▌Webアプリを作るとデータを保存したくなる ⚫ プログラムやマシンが終了してもデータが残る ⚫cf. memcached ▌色々なやり方 ⚫ 素朴にファイルに保存 ⚫自分で競合、不整合などを回避するのは大変

    ⚫大規模だと大変になる ⚫ サイボウズOffice… ⚫ データベース管理システム(DBMS) ⚫難しいことの面倒を見てくれる
  19. データベース管理システム(DBMS) ▌RDBMS / SQL ⚫ 「関係モデル」というものを扱うデータベース ⚫ SQLという言語で操作する ⚫ 後日詳しくやります

    ▌NoSQL ⚫ SQLへ対抗して出てきたデータベース(大抵速いがトレードオフ有り) ⚫キーバリューストア(KVS) ⚫ キーとバリューのペアの形式だけ保存 ⚫ドキュメント指向データベース ⚫ 柔軟な構造のデータを保存
  20. ログイン ▌Webアプリにはほぼ必須な機能 ⚫ ログインした後、別のページから戻ってきてもログインさ れたまま ⚫ どう実現する?

  21. Cookie (RFC 6265) ▌サーバー側からクライアントにデータを保存される仕組み ⚫ サーバー:「Set-Cookie: <キー>=<値> 」というヘッダー を載せてレスポンスを返す ⚫クライアントはそのペアを保存する

    ⚫ クライアントはリクエストに「Cookie: <キー>=<値>」 を載せる ⚫Set-Cookieを返してきたドメインにだけ送る ▌HTTPが状態を持つことができる Set-Cookie: login=true Cookie: login=true
  22. セッション ▌一連のアクセスでデータを保持する仕組み ⚫ Cookieじゃセキュリティ的に… ⚫パスワードを毎回送る? 勝手に書き換えられたら? ⚫ データ量に限界 ▌セッション開始時(ログイン時に)ランダムな IDを発行

    ⚫ それをCookieに保持する ⚫ データはIDをキーにサーバー側に保存する Set-Cookie: lD=42 Cookie: ID=42 42, user = aono 42, loginTime= 10:12 104, user=akai …
  23. パスワードの保存 ▌ログインできるWebアプリを作る場合ユーザー登録が必要 ⚫ 多くの場合、ユーザー名とパスワードを登録させる ⚫ パスワードをデータベースに保存していい? ⚫ 情報流出したら?

  24. パスワードのハッシュ化 ▌パスワードはハッシュ関数を通したハッシュ値を保存する ⚫ ログイン時は入力されたパスワードのハッシュ値を取り、保存 されているハッシュ値と比較 ⚫ 一致すればOK ▌ハッシュ関数 ⚫ 任意の長さのバイト列から固定長のバイト列を出力

    ⚫ 出力から入力の値の推測が難しい ⚫ SHA-2, SHA-1, MD5 など ⚫ より安全に: salt, HMAC... SHA-1の例 'password' → 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8 '123456' → 7c4a8d09ca3762af61e59520943dc26494f8941b
  25. HTTPS ▌HTTPは通信内容が丸見え ⚫ パスワードを送ったら?セッションID見られたら? ▌HTTPをTLSで暗号化して通信する→HTTPS ⚫ 内容を見られない。改ざんされない。なりすまされない。 ⚫ cybozu.comは必ずHTTPSを使う ⚫

    現代では必須 (商用なら)
  26. HTTPは事実上必須

  27. QUALYS SSL LABS ▌cybozu.comは安全

  28. Webアプリケーションフレームワーク ▌Webアプリを作るのに便利な機能が詰まったライブラリ ⚫ HTTPの処理、Cookie、データベースへのアクセス、テンプ レートエンジン などなど ⚫ 現代でWebアプリを新たに作るなら、何らかのフレーム ワークを使うことになる ▌Ruby

    on Rails, Spring Framework, Django などが有名所 ⚫ 死んでいったフレームワーク達も数知れず ⚫ 独自のフレームワークが生み出されることも…
  29. フロントエンド

  30. HTML ▌文書に構造や意味を与えるための言語 ⚫ 見出し、段落、他の文書へのリンク、… ⚫ <h1></h1>, <p></p>, <a href=”https://~”></a>, …

    ▌それぞれのタグがどういう意味を持つからルールで決まっている ⚫ https://www.w3.org/TR/html5/ ⚫ 正しい使い方をする→機械が読める→スクリーンリーダが読め る→アクセシブル ▌講義では詳しくはやらないので、自分で調べてね
  31. テンプレートエンジン ▌HTMLの中にデータを埋めたり、プログラム的に表示を変える 仕組み ⚫ JSP, Freemarker, PHP, Smarty, eRuby, …

    ▌動的にHTMLを組み立てるためのツール <div> こんにちは! ${user.name}さん。 <#if user.isAdmin > あなたは管理者です。 </#if> </div> + user.name = “赤井” user.isAdmin = false <div> こんにちは! 赤井さん。 </div>
  32. CSS ▌HTMLの文書の見た目を決めるための仕組み ⚫ 文字の大きさ、色、背景、…。 ▌意味と見た目を分離する ⚫ HTMLには見た目を書かない ▌地道に調整しないといけないので、大変な世界…

  33. JavaScript ▌現代のWebアプリはサーバー側だけでは完結しない ⚫ JavaScriptをブラウザで動かしてダイナミックな動作をする ⚫ DOM操作 ⚫JavaScriptを使って、画面を書き換える。 ⚫ Ajax/XHR ⚫JavaScriptからHTTP通信を行う。画面遷移せずに色々なアクションを行える。

    ⚫ フレームワーク: ⚫JavaScriptにもフレームワークがたくさん ⚫React, Vue, Closure Libarary, etc.
  34. Web API ▌Webアプリケーションの処理をネットワーク越しに呼び出す ⚫ HTMLではなくデータ(JSON, XML等)を返す ⚫ サーバー内のデータを更新する ⚫ JavaScriptから呼ぶ

    ▌例えば、kintoneはHTMLの生成は最低限 ⚫ ほとんどAPIを呼び出している ▌サーバーとクライアントの分離が出来てシンプルになる傾向
  35. ▌Webアプリケーションはここで説明しなかったものも含め、 たくさんの要素が組み合わさって出来ている ⚫ この講義は取っ掛かり。 ⚫ 随時知っていきましょう

  36. 演習課題

  37. 準備 ▌Python3のインストール ⚫ https://www.python.org/downloads/release/python-372/ ⚫ macOS 64-bit installer を使用 ⚫

    Homebrew で入れてもOK
  38. 演習課題(1) ▌Socketを使ったプログラムを書いてみる ⚫ 雛形は用意してあるので、read/write を書く。 ⚫ Echoサーバーを作る。 ⚫受信したものをそのまま送信するサーバー ⚫ 1行毎、1文字毎、等、出力の仕方はおまかせ

    ⚫ 単純なやり方では複数のリクエストを同時に扱えないことを確認し てみる
  39. 演習課題(1) やり方 ▌./server.py で実行 ▌telnet localhost 12345 で接続 ▌別のシェルから同時にtelnet してみる

  40. 演習課題(2) ▌CGIを書いてみる ⚫ CGIライブラリを使わずに ⚫ まずは現在時刻を表示する ⚫ HTMLを出力してブラウザから開いてみよう ⚫ そのた動的に結果が変わるものを自由に試す

  41. 演習課題(2) ▌./cgiserver.py を実行してWebサーバーを起動 ▌./cgi-bin/test_cgi.py を編集 ▌http://localhost:8000/cgi-bin/test_cgi.py にアクセス

  42. 演習課題(3) ▌時間があれば ▌演習課題(1)で作成したサーバーを複数のコネクションを同時 に扱えるようにする ⚫ スレッドを使うなど

  43. 使用した画像のライセンス

  44. By RRZEicons [CC BY-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0)], via Wikimedia Commons https://commons.wikimedia.org/wiki/File%3AServer-multiple.svg

    By Sir Stig (Own work (Transfered by Mono)) [CC BY-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0) or GFDL (http://www.gnu.org/copyleft/fdl.html)], via Wikimedia Commons https://commons.wikimedia.org/wiki/File%3AAluminium_MacBook.png