Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

Webサーバーは何をする?

Slide 5

Slide 5 text

Webサーバー ▌HTTPを処理するサーバー ⚫ クライアントからリクエ ストを受け付けて ⚫ 所望の結果を返す ▌Apache, IIS, nginx... request: index.htmlください response: index.html どうぞ!

Slide 6

Slide 6 text

Webサーバーがやること ▌リクエストを受け付ける ▌結果を(読み込む|計算する) ▌結果を送り返す ▌つまり、Input-Process-Output ⚫ InputとOutputはネットワークの処理 ⚫ This is “Program”

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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);

Slide 9

Slide 9 text

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);

Slide 10

Slide 10 text

複数のリクエストが来たら ▌サーバーが1つのリクエストを処理している時に別のリクエス トが来る ⚫ 前のページのコードだとどうなる?

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

プロセス ▌プログラムの実行の単位 ⚫ コマンドやアプリを起動するとプロセスが立ち上がる ⚫ 別のプロセスのメモリにはアクセスできない ⚫ 異なるプロセスは並列に動くことができる ▌Webサーバーでは ⚫ リクエストを受付 ⚫ 処理プロセスを起動してソケットを引き継ぐ

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

Webアプリケーション

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

CGI: Common Gateway Interface ▌Webサーバーとプログラムがやりとりするためのインターフェース ⚫ リクエストが来るたびにアプリのプロセスを起動する ⚫ リクエストの内容は、環境変数や標準入力で渡される ⚫ 結果は標準出力で返す ▌昔はこのやり方が主流 ⚫ Perlの時代 ⚫ 毎回プロセスを起動するので遅い ⚫ サイボウズ Office / メールワイズは今でもこれ request response program stdin/env stdout

Slide 17

Slide 17 text

Webアプリケーションサーバー ▌Webアプリケーションを実行するサーバー ⚫ CGIと異なり、通常起動しっぱなし ⚫ Webサーバーがアプリケーションサーバーにリクエストを 中継する ⚫主にHTTPでやりとり ⚫ アプリケーションサーバーとアプリの間 ⚫特定のメソッドを呼んだりしてやりとり request response App server request response App

Slide 18

Slide 18 text

永続化/データベース ▌Webアプリを作るとデータを保存したくなる ⚫ プログラムやマシンが終了してもデータが残る ⚫cf. memcached ▌色々なやり方 ⚫ 素朴にファイルに保存 ⚫自分で競合、不整合などを回避するのは大変 ⚫大規模だと大変になる ⚫ サイボウズOffice… ⚫ データベース管理システム(DBMS) ⚫難しいことの面倒を見てくれる

Slide 19

Slide 19 text

データベース管理システム(DBMS) ▌RDBMS / SQL ⚫ 「関係モデル」というものを扱うデータベース ⚫ SQLという言語で操作する ⚫ 後日詳しくやります ▌NoSQL ⚫ SQLへ対抗して出てきたデータベース(大抵速いがトレードオフ有り) ⚫キーバリューストア(KVS) ⚫ キーとバリューのペアの形式だけ保存 ⚫ドキュメント指向データベース ⚫ 柔軟な構造のデータを保存

Slide 20

Slide 20 text

ログイン ▌Webアプリにはほぼ必須な機能 ⚫ ログインした後、別のページから戻ってきてもログインさ れたまま ⚫ どう実現する?

Slide 21

Slide 21 text

Cookie (RFC 6265) ▌サーバー側からクライアントにデータを保存される仕組み ⚫ サーバー:「Set-Cookie: <キー>=<値> 」というヘッダー を載せてレスポンスを返す ⚫クライアントはそのペアを保存する ⚫ クライアントはリクエストに「Cookie: <キー>=<値>」 を載せる ⚫Set-Cookieを返してきたドメインにだけ送る ▌HTTPが状態を持つことができる Set-Cookie: login=true Cookie: login=true

Slide 22

Slide 22 text

セッション ▌一連のアクセスでデータを保持する仕組み ⚫ Cookieじゃセキュリティ的に… ⚫パスワードを毎回送る? 勝手に書き換えられたら? ⚫ データ量に限界 ▌セッション開始時(ログイン時に)ランダムな IDを発行 ⚫ それをCookieに保持する ⚫ データはIDをキーにサーバー側に保存する Set-Cookie: lD=42 Cookie: ID=42 42, user = aono 42, loginTime= 10:12 104, user=akai …

Slide 23

Slide 23 text

パスワードの保存 ▌ログインできるWebアプリを作る場合ユーザー登録が必要 ⚫ 多くの場合、ユーザー名とパスワードを登録させる ⚫ パスワードをデータベースに保存していい? ⚫ 情報流出したら?

Slide 24

Slide 24 text

パスワードのハッシュ化 ▌パスワードはハッシュ関数を通したハッシュ値を保存する ⚫ ログイン時は入力されたパスワードのハッシュ値を取り、保存 されているハッシュ値と比較 ⚫ 一致すればOK ▌ハッシュ関数 ⚫ 任意の長さのバイト列から固定長のバイト列を出力 ⚫ 出力から入力の値の推測が難しい ⚫ SHA-2, SHA-1, MD5 など ⚫ より安全に: salt, HMAC... SHA-1の例 'password' → 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8 '123456' → 7c4a8d09ca3762af61e59520943dc26494f8941b

Slide 25

Slide 25 text

HTTPS ▌HTTPは通信内容が丸見え ⚫ パスワードを送ったら?セッションID見られたら? ▌HTTPをTLSで暗号化して通信する→HTTPS ⚫ 内容を見られない。改ざんされない。なりすまされない。 ⚫ cybozu.comは必ずHTTPSを使う ⚫ 現代では必須 (商用なら)

Slide 26

Slide 26 text

HTTPは事実上必須

Slide 27

Slide 27 text

QUALYS SSL LABS ▌cybozu.comは安全

Slide 28

Slide 28 text

Webアプリケーションフレームワーク ▌Webアプリを作るのに便利な機能が詰まったライブラリ ⚫ HTTPの処理、Cookie、データベースへのアクセス、テンプ レートエンジン などなど ⚫ 現代でWebアプリを新たに作るなら、何らかのフレーム ワークを使うことになる ▌Ruby on Rails, Spring Framework, Django などが有名所 ⚫ 死んでいったフレームワーク達も数知れず ⚫ 独自のフレームワークが生み出されることも…

Slide 29

Slide 29 text

フロントエンド

Slide 30

Slide 30 text

HTML ▌文書に構造や意味を与えるための言語 ⚫ 見出し、段落、他の文書へのリンク、… ⚫

,

, , … ▌それぞれのタグがどういう意味を持つからルールで決まっている ⚫ https://www.w3.org/TR/html5/ ⚫ 正しい使い方をする→機械が読める→スクリーンリーダが読め る→アクセシブル ▌講義では詳しくはやらないので、自分で調べてね

Slide 31

Slide 31 text

テンプレートエンジン ▌HTMLの中にデータを埋めたり、プログラム的に表示を変える 仕組み ⚫ JSP, Freemarker, PHP, Smarty, eRuby, … ▌動的にHTMLを組み立てるためのツール
こんにちは! ${user.name}さん。 <#if user.isAdmin > あなたは管理者です。
+ user.name = “赤井” user.isAdmin = false
こんにちは! 赤井さん。

Slide 32

Slide 32 text

CSS ▌HTMLの文書の見た目を決めるための仕組み ⚫ 文字の大きさ、色、背景、…。 ▌意味と見た目を分離する ⚫ HTMLには見た目を書かない ▌地道に調整しないといけないので、大変な世界…

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

Web API ▌Webアプリケーションの処理をネットワーク越しに呼び出す ⚫ HTMLではなくデータ(JSON, XML等)を返す ⚫ サーバー内のデータを更新する ⚫ JavaScriptから呼ぶ ▌例えば、kintoneはHTMLの生成は最低限 ⚫ ほとんどAPIを呼び出している ▌サーバーとクライアントの分離が出来てシンプルになる傾向

Slide 35

Slide 35 text

▌Webアプリケーションはここで説明しなかったものも含め、 たくさんの要素が組み合わさって出来ている ⚫ この講義は取っ掛かり。 ⚫ 随時知っていきましょう

Slide 36

Slide 36 text

演習課題

Slide 37

Slide 37 text

準備 ▌Python3のインストール ⚫ https://www.python.org/downloads/release/python-372/ ⚫ macOS 64-bit installer を使用 ⚫ Homebrew で入れてもOK

Slide 38

Slide 38 text

演習課題(1) ▌Socketを使ったプログラムを書いてみる ⚫ 雛形は用意してあるので、read/write を書く。 ⚫ Echoサーバーを作る。 ⚫受信したものをそのまま送信するサーバー ⚫ 1行毎、1文字毎、等、出力の仕方はおまかせ ⚫ 単純なやり方では複数のリクエストを同時に扱えないことを確認し てみる

Slide 39

Slide 39 text

演習課題(1) やり方 ▌./server.py で実行 ▌telnet localhost 12345 で接続 ▌別のシェルから同時にtelnet してみる

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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