見出し画像

『JavaScriptを極める3ヶ月 アプリ開発に使える知識を徹底的に学ぶ』という勉強会の4~8日目をまとめる(前編)

やべぇよ・・・やべぇよ・・・

毎週の更新途絶えてしまいました、、、
すみません、、、

今から1日ずつの内容を乗せていく、、、と書きたいですが今現在書く時間がなかなか取れないので4日分を前編、後編とまとめて書いていきたいと思います。

このnoteではX-HACK様の主催する勉強会の『JavaScriptを極める3ヶ月 アプリ開発に使える知識を徹底的に学ぶ』という勉強会の学んだことについて備忘録&復習としてまとめてみようと思います。


※この記事を見る前提知識としてJavaScriptの基本文法とオブジェクト指向&プロパティの概念、簡単なchromeデベロッパー・ツールの使い方を覚えておくと読みやすいと思います。
また、今回からVue.jsというフレームワークを使います。
どのようなものか、簡単ですが解説しております。今回はチュートリアルの解説をしていき、後半はコードを読んでいきます。

あ、あと「JavaScriptを極める3ヶ月 アプリ開発に使える知識を徹底的に学ぶ」の第2期生も募集しているらしいです。

興味があれば是非行ってみてくださいね(ダイレクトマーケティング)

前回はこちら

1.今回の内容とゴール

内容
・フロントエンド側が覚えてほしいバックエンドの知識
 「認証・認可」「セッション・クッキー」

・Vue.jsって?どんなフレームワーク?

・チュートリアルを見てみる(今回はここまで)

・ToDoリストを完成する。(後半)

まず、フロントエンドが覚えてほしい「ログイン」と
「セッション・クッキー」について解説していきたいと思います。

2.フロントエンド側が覚えてほしいバックエンドの知識1「認証・認可」

さて、皆様がよく行っている「ログイン」とは
一体どのような仕組みになっているのでしょうか?

答えを言いますとログインとは、「認証・認可を行うこと」であります。
では「認証・認可」とは何でしょうか?

認証と認可は密接に絡み合っている一方で全く別の概念です。
・認証:通信の相手が誰(何)であるかを確認すること
・認可:とある特定の条件に対して、リソースアクセス
    の権限を与えること)
出典:よくわかる認証と認可 | Developers.IO

ということになります。しかし認可の方では複雑なプロセスがあります。

認可のほうは、「誰が」、「誰に」、「何の権限を」、という三つの要素が出てくるため、複雑になります。加えて、話をややこしくしているのは、この三つの要素のうち、「誰が」を決める処理が「認証処理」であるという点です。すなわち、認可処理にはその一部として認証処理が含まれているため、話がややこしくなっているのです。
出典:OAuth 2.0 + OpenID Connect の
        フルスクラッチ実装者が知見を語る-Qiita

という風に「認可」の方のプロセスで「認証処理」をする場面があるので
話が複雑になることがあるようですね。
今回の話は前者の考え方のみを頭に入れた状態で話していきます。

さて、「ログイン」についての話に戻りますが、よくある「ログイン」する
までの手順をざっと書いてみます。

1、 アカウント作成画面があって、メルアドと任意のパスワードを
  セットする
2、送信ボタンを押す
3、 登録メルアドにメールが届く
4、メールの本文にリンクが貼ってあって、それをクリックすると、アカウンが作られる
5、今後はメルアドとパスワードでそのサービスにログインできる

実際に行っている画面を見せながらやっていきます。
今回はおなじみのQiitaで行います。

1、 アカウント作成画面があって、メルアドと任意のパスワードを
  セットする

画像1

ユーザー名等を入力します。

2、送信ボタンを押す

ここでは登録するボタンを押します。
その時に入力したデータはデータベースへ送られます。
このような形でデータベースへ保存されます。(あくまで想像です)

画像3

※データベースとは大量のデータが保存されている所を指します。


3、 登録メルアドにメールが届く 

その後、このようなメールが届くと思います

画像2

 登録されたメールアドレスが本人のものかを
確認するために送られてきます。


ここで一つ疑問が出ました。
「ユーザー登録している人数が多数いるのにどのようにして識別しているのだろう?あとなんで24時間という制限時間あるん?」と。
その答えとなるのが「トークン」です。
ここのURLの最後にある「token=~~~」
の「~~~」の部分がトークンです。ここのコードで個別で識別
しているのですね。

ちなみにトークンが読み取られてしまうと、そこから個人情報を
抜き取られる恐れがあります。
パスワードクラックの手法として有名な総当たり攻撃
(ブルートフォースアタック)や辞書攻撃にさらされる危険があるのです。


そのためにトークンを長文化し、かつ有効期限が決められているのですね!

4、メールの本文にリンクが貼ってあって、それをクリックすると
  アカウントが作られる 

5、今後はメルアドとパスワードでそのサービスにログインできる

という流れになり。アカウントのページとなります。

さて、ここでも1つ疑問が。
同じURLへ移動するとき、ログインしているときと
ログインしていないときには
違うページが出てくることがありませんか?

例えば「https://qiita.com/」を表示させると、、、

ログインしていない状態

画像5

ログインしている状態

画像5

同じURLでもログインしている状態とそうでない状態では
違うことが確認できていると思います。

どのようにして、ログインを識別しているのか?
その仕組みとして「クッキー」というものがあります。

3.フロントエンド側が覚えてほしいバックエンドの知識2「セッション・クッキー」

まず「クッキー」を知るためには「セッション」というものを知る必要がありますが、それは一体何でしょうか?

セッションとは、活動期間、学期、会期、開催期間、集会などの意味を持つ英単語。コンピュータシステムやネットワーク通信において、接続/ログインしてから、切断/ログオフするまでの、一連の操作や通信のこと。
出典:IT用語辞典 e-Words --- セッション 【 session 】

とあります。今回の場合はクライアント側とサーバー側の一連の操作を
指します。

さて、このセッションを行っているHTTPというプロトコルがあります。

HTTPについて分からない方は、とよももさんの記事を参照にしてください。
とっても分かりやすい記事です。

さて、このHTTPは「ステートレス」な状態です。
「状態がない」という意味ですがこちらの記事を参考に見てみましょう。

(ステートフルの例):
客: こんにちは
店員: いらっしゃいませ。○○バーガーへようこそ
客: ハンバーガーセットをお願いします
店員: サイドメニューは何になさいますか?
客: ポテトで
店員: ドリンクは何になさいますか?
客: ジンジャーエールで
店員: +50円でドリンクをLサイズにできますがいかがですか?
客: Mでいいです
店員: 以上でよろしいですか?
客: はい
店員: かしこまりました

(ステートレスの例):
客: こんにちは
店員: いらっしゃいませ。○○バーガーへようこそ
客: ハンバーガーセットをお願いします
店員: サイドメニューは何になさいますか?
客: ハンバーガーセットをポテトでお願いします
店員: ドリンクは何になさいますか?
客: ハンバーガーセットをポテトとジンジャーエールでお願いします
店員: +50円でドリンクをLサイズにできますがいかがですか?
客: ハンバーガーセットをポテトとジンジャーエール(M)でお願いします
店員: 以上でよろしいですか?
客: ハンバーガーセットをポテトとジンジャーエール(M)でお願いします。以上
店員: かしこまりました
出典:ステートレスとは - Qiita

という「状態を持てない」ので今までの情報を記録することができません。(一回一回最初から言わなければならない)エンジニアの方はURLのディレクトリを想像した方がわかりやすいでしょう。

さて、この状態でログインをしようとすると、、、

例えば、「ログイン」ページの場合、「ログインしているかどうか」のチェックをする必要がある。
NG例)
http://www.littleforest.jp/itemlist?login=ok
loginパラメータを調べてokかどうかを調べる。
→→パラメータを容易に改変できてしまう。
出典:Cookieとセッションをちゃんと理解する - Qiita

このようにHTPPはステートレスのままだと色々不便なので
ユーザー識別をするためにセッション管理機能という
機能が使われています。

セッション管理機能は、ユーザーが Web サーバーにアクセスした際に、ユーザーを識別する整理番号であるセッション ID をユーザーに渡します。ユーザーは、リクエストする度にセッション ID を送信することで、Web サーバー側でユーザーを識別できるようになります。
セッション ID は通常 Cookie に保存されます。
出典:セッション管理機能|Webセキュリティの小部屋

ここでクッキーの名前が出ましたね。要するにクッキーというのは
「ユーザー識別をするために、サーバーからセッションIDを受け取り
クライアント側ではセッションIDを、クッキーというところで保存される」
ということになります。


さてchromeのデベロッパーツールを使いログインする前と
ログインした後のクッキーの変化を見てみたいと思います。
右クリックで「検証」→上のタブバーで「application」→左のところの「storage」という部分の「cookies」の中の「https://qiita.com」を選択

ログインする前

画像6

ログインした後

画像7

ログインした後では「secure_token」と「user_session_key」が
増えてますね!この情報を毎回サーバーに送り「あ、今この状態だから
このページを送ろう」とサーバーはステートフルな
振る舞いをしてくれます。

ちなみにクッキーに関するセキリティ問題として
「セッションハイジャック」という問題があります。

セッションIDを知られてしまい「なりすまし行為」されてしまう
行為のことですね、、、
Webアプリを作る人は「攻撃者にセッションIDを察知されない」仕組みを作ることを忘れないようにしましょう!


4.Vue.jsって?どんなフレームワーク?

さて、2020年現在Vue.jsというフレームワークをよく聞くと思います。
さて、Vue.jsとは一体なんでしょうか?

Vue (発音は / v j u ː / 、 view と同様)はユーザーインターフェイスを構築するためのプログレッシブフレームワークです。他の一枚板(モノリシック: monolithic)なフレームワークとは異なり、Vue は少しずつ適用していけるように設計されています。中核となるライブラリは view 層だけに焦点を当てています。そのため、使い始めるのも、他のライブラリや既存のプロジェクトに統合するのも、とても簡単です。また、モダンなツールやサポートライブラリと併用することで、洗練されたシングルページアプリケーションの開発も可能です。(引用)

とあります。MVCモデルのview部分(大雑把に言えばUI部分)の設計に特化したフレームワークなのです。

また、後々後述しますがホームページの『コンポーネント』ごとに記述を分ける事ができます。

画像8

それにより、

・コンポーネントごとに動きを独立する事ができるので
 コンポーネントごとの記述などに役割分担ができ開発効率が上がる。

・CSSの記述を汚す事がない。

・改良がピンポイントでできる

など柔軟な記述ができるようになります。(これらはVue-Cliを導入することにより強く認識することができるでしょう。Vue-Cliの導入は後々投稿します)

また、一つのホームページに色々なシステムを持たせる事ができるSPA(シングルページアプリケーション)が作りやすいという利点もありますね。

Vue.jsの特徴やどのような動きをするか、動画で見たい方はこちら。



英語ですが、わかりやすいアニメーションを使ったり実際にコードを書いて
実例をしているのでJavaScriptを理解できている人はわかるでしょう。

また同じようなUIフレームワークにReactがありますが初心者はVue.jsの方が扱いやすいらしいです。(Reactはまだ触ってないので『らしい』で記述します)

5.チュートリアル(バインディング、ディレクティブ)

ここではチュートリアルに則って書いていきますが、重要な部分のみを書いていきたいと思います。

今回はCDNを使います。これはテキストエディタにscriptタグを入れるだけで使用できる仕組みとなっております。

まずはHello Vue!を表示させましょう。

<!DOCTYPE html>
<html lang="ja">
 <head>
   <meta charset="UTF-8" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
   <meta http-equiv="X-UA-Compatible" content="ie=edge" />
   <title>Hello World</title>
 </head>
 <body>
   <div id="app">
     {{ message }}
   </div>
   <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
   <script>
     var app = new Vue({
       el: "#app",
       data: {
         message: "Hello Vue!"
       }
     });
   </script>
 </body>
</html>

これで、ブラウザを開いたら「Hello Vue!」と出るはずです。

<div id="app">

でHTMLをラップして。

     var app = new Vue({
       el: "#app",
       data: {
         message: "Hello Vue!"
       }
     });

で記述しているのですね!


パッと見たところただテンプレートを貼っただけと思いますが
実は

{{ message }}

 message: "Hello Vue!"

はリアクティブな関係になっています。

以下の動画を見てください。

コンソールを使ってapp.messageの値を変更すると表示が変わりましたね!

さて次にメッセージのバインディングをさせましょう。

<!DOCTYPE html>
<html lang="ja">
 <head>
   <meta charset="UTF-8" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
   <meta http-equiv="X-UA-Compatible" content="ie=edge" />
   <title>Hello World</title>
 </head>
 <body>
   <div id="app-2">
     <span v-bind:title="message">
       Hover your mouse over me for a few seconds to see my dynamically bound
       title!
     </span>
   </div>
   <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
   <script>
     var app2 = new Vue({
       el: "#app-2",
       data: {
         message: "You loaded this page on " + new Date().toLocaleString()
       }
     });
   </script>
 </body>
</html>

このように打ち込んで、コンソールで
app2.messageと打ち込んでみましょう。

無題

//コンソール
app2.message
"You loaded this page on 2020/1/29 18:47:11"

と「"You loaded this page on " + new Date().toLocaleString()」の中身が表示されていますね!

このように、HTMLとVueの中身を結びつけることをバインディングといいます!

と、いってもいまいちわかりにくいですね笑。

実感しやすいように双方向バインディングというものを実感しましょう。

<!DOCTYPE html>
<html lang="ja">
 <head>
   <meta charset="UTF-8" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
   <meta http-equiv="X-UA-Compatible" content="ie=edge" />
   <title>Hello World</title>
 </head>
 <body>
   <div id="app-6">
     <p>{{ message }}</p>
     <input v-model="message" />
   </div>
   <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
   <script>
     var app6 = new Vue({
       el: "#app-6",
       data: {
         message: "Hello Vue!"
       }
     });
   </script>
 </body>
</html>

このように、表示される部分とメッセージボックスが連動するように
なりましたね!コンソールでも場所を指定して文字を入れても
連動するようなっています!

ここでまた重要なことが1つ。「v-bind」「v-model」についてです。これらはディレクティブといい、どのような働きをするのか指示をする役割を持ちます。これらの働きを覚えることがVueを使いこなすコツですね!

ほかにも条件分岐に使う「v-if」、繰り返しに使う「v-for」など、、、
色々あるので是非試してください!

6.チュートリアル(コンポーネント)

さて、次は「コンポーネント」という概念について学びましょう!
まずはチュートリアルを見ましょう。

コンポーネントシステムは Vue.js におけるもうひとつの重要な抽象概念です。「小さく、自己完結的で、(多くの場合)再利用可能なコンポーネント」を組み合わせることで、大規模アプリケーションを構築することが可能になります。アプリケーションのインターフェイスについて考えてみると、ほぼすべてのタイプのインターフェイスはコンポーネントツリーとして抽象化することができます。

画像10

分かるような分からないような・・・コードを書いてみましょう!

<!DOCTYPE html>
<html lang="ja">
 <head>
   <meta charset="UTF-8" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
   <meta http-equiv="X-UA-Compatible" content="ie=edge" />
   <title>Hello World</title>
 </head>
 <body>
   <div id="app">
     <ol>
       <todo-item></todo-item>
     </ol>
   </div>
   <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
   <script>
     Vue.component("todo-item", {
       template: "<li>This is a todo</li>"
     });

     var vm = new Vue({
       el: "#app",
       data: {}
     });
   </script>
 </body>
</html>

画面に「1、This is a todo」と出たのが分かるでしょうか?
HTML側の

<todo-item></todo-item>

と、script側の

Vue.component("todo-item", {
       template: "<li>This is a todo</li>"
     });

のように「todo-item」でつながってtemplateで描写されていることが分かると思います。
もう少し書いてみましょう。

<!DOCTYPE html>
<html lang="ja">
 <head>
   <meta charset="UTF-8" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
   <meta http-equiv="X-UA-Compatible" content="ie=edge" />
   <title>Hello World</title>
 </head>
 <body>
   <div id="app-7">
     <ol>
       <!-- todos 配列にある各 todo に対して todo-item コンポーネントのインスタンスを作成する -->
       <todo-item
         v-for="item in groceryList"
         v-bind:todo="item"
         v-bind:key="item.id"
       ></todo-item>
     </ol>
   </div>
   <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
   <script>
     Vue.component("todo-item", {
       props: ["todo"],
       template: "<li>{{ todo.text }}</li>"
     });

     var app7 = new Vue({
       el: "#app-7",
       data: {
         groceryList: [
           { id: 0, text: "Vegetables" },
           { id: 1, text: "Cheese" },
           { id: 2, text: "Whatever else humans are supposed to eat" }
         ]
       }
     });
   </script>
 </body>
</html>

結果として
1.Vegetables
2.Cheese
3.Whatever else humans are supposed to eat
と描写されました。

少しわかりにくいので解説します。

まずapp7.groceryListの配列に注目してください。

         groceryList: [
           { id: 0, text: "Vegetables" },
           { id: 1, text: "Cheese" },
           { id: 2, text: "Whatever else humans are supposed to eat" }
         ]

配列に3つのオブジェクトと、オブジェクトの中に各2つのプロパティが
入っていますね。

       <todo-item
         v-for="item in groceryList"
         v-bind:todo="item"
         v-bind:key="item.id"
       ></todo-item>
     Vue.component("todo-item", {
       props: ["todo"],
       template: "<li>{{ todo.text }}</li>"
     });

「</todo-item>」に注目してください。タグの中に書いてある
「v-for="item in groceryList"」これが
「 groceryList内の配列をitemとしてループせよ」と指示を出しています。
そして、「v-bind:todo="item"」と書きitemを「props: ["todo"],」
としてバインディングさせています。
それと同時に「v-bind:key="item.id"」もバインディングさせています。
そして、それらのデータを「 template: "<li>{{ todo.text }}</li>"});」
を使い、HTMLに描写されているわけなのです。
※ちなみに{{todo.text}}は「app7.groceryList[x].text」です。

ちなみに、このcomponentの考えはVue.cil、Nuxtを使うと実感しますが
役割分担するというではかなり強力な考えです。
この仕組みを使い、外部データのように
役割ごとにファイルを分割できるからです。

「APIリクエストのコードはここのファイルね」とか
「この動きを再利用する時ここのファイルに入れてタグで呼び出そう」とかとか、、、コードが多いときに役立つでしょう。

さて、次回はTodoリストを作っていきます。
お楽しみに!

この記事が気に入ったらサポートをしてみませんか?