Web App開発をしたいなら知っておくべき基礎知識

# はじめに
Web Appとは、ChromeやFirefoxといったWebブラウザ上で動作するアプリケーションソフトウェアです。必要に応じて、クライアントがWebサーバとやりとりをすることで「記事を投稿」「ユーザ登録」など高度な機能を実現することができます。本記事では以下のことについて勉強します。

<ul>
    <li><a href="#クライアントサーバモデル">クライアント/サーバモデル</a></li>
    <li><a href="#httpメソッド">HTTPメソッド</a></li>
    <li><a href="#ステータスコード">ステータスコード</a></li>
    <li><a href="#uri">URI</a></li>
    <li><a href="#json">JSON</a></li>
    <li><a href="#cookie">Cookie</a></li>
    <li><a href="#セキュリティ">セキュリティ</a></li>
</ul>

# クライアント/サーバモデル
多数のクライアントに対して、少数のサーバが対応するモデルです。プロセスをクライアントとサーバに分けることで、プロセス間の通信を構造化するのを目的としています。

- クライアント
    - Webブラウザなど。サーバにサービス要求を送信し、サーバの応答を待つ。
- サーバ
    - Webサーバ、DBサーバなど。クライアントからの処理を受け付け、処理を行う。

クライアントからサーバに要求 → サーバで処理 → サーバからクライアントに応答
という流れになります。
![スクリーンショット 2022-11-06 190007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742387/b5da52d0-d3c3-fc18-82cd-0e4477d4fdca.png)

# HTTPメソッド
代表的なものを挙げます。
- GET
- POST
- PUT
- DELETE

ただ、PUT・DELETEに関しては大抵POSTで代用できてしまうので、実際にはGETとPOSTが理解できてれば大丈夫です。ざっくり言うと、PUTはリソースの更新、DELETEは削除を行うものです。

では、GETとPOSTについて見ていきましょう。

- GET
    - リソースを取得するためのメソッド。Webサイトにアクセスしたとき、クライアントからサーバにGETリクエストを送信し、Webページのhtmlなどを受け取って画面を表示します。
    - クエリパラメータを使って、クライアントからサーバに任意の情報を送ることができます。
        - 例)`https://example.com/hoge?id=2&name=tanaka`
        - ?の後ろがクエリパラメータ
        - idが2、nameが"tanaka"という情報をサーバに送信している
- POST
    - リソースを作成するためのメソッド。機密性の高いデータや、大量のデータを送信したいときに使います。
    - GETと違って、送信される情報はURLではなく、HTTPリクエスト内のメッセージボディに格納されます。

データ送信自体は、GETでもできます。ですが、URLから送信した情報が丸見えになったり、大量のデータを送るとURLの長さがとんでもないことになります。特性を理解し、状況に応じてGETとPOSTを使い分けてください。

htmlのformタグはデフォルトではGETメソッドを使って情報を送信するようになっているので、POSTを使うときには明示する必要があります。

```html
<form action="#" method="post">
    <input name="id">
    <button type="submit">送信</button>
</form>
```
# ステータスコード
404 Not Foundとか見たことあると思います。この番号がステータスコードです。この番号それぞれに割り当てられた意味を知っておけば、デバッグの際などに非常に役に立ちます。特によく見るものについて列挙します。
- 200
    - リクエストが正常に完了
- 301
    - 恒久的なリダイレクト
- 302
    - 一時的なリダイレクト
- 401
    - 認証が必要
- 403
    - アクセスが禁止されているコンテンツ
- 404
    - 存在しないコンテンツ
- 500
    - サーバ内でエラー

また、400番台のエラーはクライアント側、500番台のエラーはサーバ側に問題がある可能性が高いということを頭に入れておきましょう。

ステータスコードはChromeとかのデベロッパーツールを用いて確認できたりするので、エラーがでたときには見るようにしてください。

![スクリーンショット 2022-11-06 132212.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742387/76bc4bad-a120-34ce-214c-34753b1bfde4.png)


# URI
Web上で、Webサイトや画像などといったリソースを一意に指定するものです。似た言葉にURLがありますね。URIはURLの上位概念といった定義なのですが、実用上はURI≒URLと思っていても差支えないです。
```
https://www.example.com:8080/hoge/index.html?key1=value1&key2=value2
```
では、これをパーツ毎に分解して見てみましょう。
- スキーム
    - https
    - 利用するプロトコルを表す
- ホスト名
    - www
    - コンピュータを一意に識別する
- ドメイン名
    - example.com
    - ネットワークを一意に識別する
- ポート番号
    - :8080
    - 接続するサーバのポート番号
    - 普段は省略される
- パス
    - /hoge/index.html
    - サーバ内でのリソースの場所
- クエリ
    - key1=value1&key2=value2
    - Webサーバに提供する情報


# JSON
以下のようなフォーマットで記述されるものです。
```json:hoge.json
{
    "id": 2,
    "name": "tanaka",
    "gender": "man"
}
```
データ構造を表すことができ、データの送受信によく使用されます。特にWeb APIを使ったWeb Appを作りたいなら理解が必須の知識です。APIの例を挙げると以下のようなものがあります。
- <a href="https://openweathermap.org/">OpenWeatherMap API</a>
- <a href="https://affiliate.dmm.com/api/">DMM Webサービス</a>
- <a href="https://qiita.com/api/v2/docs">Qiita API</a>

これらにデータを送信すると、特定の情報をjson形式で取得することができます。そうすることで、様々なサービスから情報を取得することが可能になります。OpenWeatherMap APIから試しに天気の情報を取得してみます。
![スクリーンショット 2022-11-06 192254.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2742387/864d0012-7c54-2a2d-3a79-41b6f58c75ce.png)

クエリパラメータでロンドンの経度・緯度を送信すると、現在の天気がjson形式にまとめられて返ってきました。このように、jsonを扱えるようになれば、様々なサービスの情報を活用できるようになり、できることの幅が広まります。

javascriptだと、json形式のデータはJson.parseというものを使って解析を行えます。
```js:script.js
const json = '{"id":2, "name": "tanaka"}';
const obj = JSON.parse(json);

console.log(obj.id) //2と出力される

console.log(obj.name) //tanakaと出力される
```

# Cookie
サーバが送信してクライアント側に保存しておく情報になります。例えば、amazonにアクセスしたとき、一度ログインすると、ページを閉じた後に戻ってきても、ログインしたままの状態になっていますよね。これを実現するのがCookieです。

HTTPはステートレスであり、誰がいつアクセスしたかという情報をサーバは持ちません。

**サーバ** 「こんにちは、あなたのお名前を教えてください。」
**ユーザ** 「○○です。」
～～～数時間後～～～
**ユーザ** 「また戻って来ました。」
**サーバ** 「こんにちは、ところであなた誰ですか？」

というようなことが起こります。しかし、Cookieがあれば、WebブラウザはサーバからもらったCookieをリクエストと一緒に送ることで、サーバは誰がアクセスしてきたかを識別することができます。

サーバはCookieに有効期限を任意の時間で設けられます。失効するのは1時間後とか、はたまた10年後といったような設定もできます。

Cookieがあれば、第三者によるログインが可能になってしまうので、くれぐれも扱いにはお気を付けて...


javascriptとかだとjs.cookie.jsというものを使ってCookieの操作ができるので興味があったら調べてみてください。


# セキュリティ
Web App開発にあたって、脆弱性をつくらないというのが最重要事項になります。考えられる攻撃は片っ端から対策しなければなりません。特に初心者で脆弱性が生まれがちなのが、「ユーザが文字を打ち込める場所」です。<br>
クロスサイトスクリプティングという攻撃について見てみましょう。例えば、Qiitaの記事の中では、以下のようなscriptタグは無効化されます。
```html
<script>window.alert("hoge")</script>
```
もし、ユーザが書き込んだ文字列がhtmlタグとして解釈されてしまったらどうなるか？
**ユーザは自分の書いたjavascriptのコードをサイト上に埋め込んで実行できます。** Qiitaの記事内でscriptタグが使えたら、この記事を訪れた人を強制的に怪しげなアダルトサイトに飛ばす...なんてことができてしまいますね。

以上の例で見た通り、Web Appに脆弱性があると利用者が被害を受けます。モダンなフレームワークでは主要な攻撃手法はデフォルトでできないようにされていますが、セキュリティの知識がないと、知らず知らずのうちにフレームワークが作ってくれた防御壁をぶち破ってしまうかもしれません。

ちなみに、クロスサイトスクリプティングは不等号に特別な意味を持たせないようにする(エスケープシーケンス)などで対策できます。

攻撃は他にも、
- バッファオーバーフロー攻撃
- SQLインジェクション
- クロスサイトリクエストフォージェリ
- ブルートフォース攻撃

などなど数えきれないほどたくさんの攻撃手法があります。全てを完璧に知っておけとは言いませんが、基本情報技術者試験で出題されるようなメジャーな攻撃手法の対策法くらいはWeb App開発前に知っておいてほしいという気持ちです。

# さいごに
今回書いた知識は氷山の一角に過ぎません。Web Appは奥が深く、ここでは紹介できていない知識が山ほどあります。ただ、Djangoとかflaskみたいなフレームワークを勉強する前に、こういった基礎知識を一度身に着けた方が深く理解しやすくなるかと思います。