PrAha Challenge 課題4 「クッキーを理解する」
こんにちは!今日はクッキーについて改めてまとめてみたいと思います!
クッキーとは
クライアントがブラウザからサーバーへリクエストをした際に、サーバーはレスポンスとしてヘッダーにSet-cookieを設定します。 再びクライアントがリクエストをすると、Set-cookieに値がセットされた状態でサーバーへリクエストし、サーバーはSet-cookieの値を認識します。
クッキーの共有
異なるサーバー間で同じクッキーを共有をすることはできません。 なぜなら、意図しない情報が含まれるクッキーが送られること防ぐためです。
では、どういう条件下においてクッキーを共有することができるのでしょうか? 調べたところ以下が上げられます。
ポートが異なる場合 ホストアドレスが一緒でポートが異なる場合(例、hoge.com:8080とhoge.com:3000)はクッキーを共有することができます。
サブドメイン サブドメイン間でクッキーを共有することが可能です。共有する場合は、クッキーのDomain属性にクッキーを受信するホストを設定します。 例えばDomain = hoge.comを設定すると、hoge.comとapi.hoge.com間でクッキーを共有することができます。
サイト跨いだアクセス
例えばサイトAとサイトBがあります。サイトA上にはサイトBのURLも記載されており、サイトA経由でサイトBにアクセスすることが可能です。 もし以前にもサイトBへ直接アクセスしたことがある場合、その時に使用したクッキーをサイトA経由アクセスした場合でも使用することも可能です。 しかし、これによりクロスサイトリクエストフォージェリ攻撃 (CSRF) を受ける可能性があります。 そこで、SameSite属性にStrictやLaxを設定すると、別サイト経由でのアクセスによるクッキーの使用を防ぐことができます。これによりCSRF攻撃を避けることが可能となるわけです。
クッキーへのアクセス制限
- Secure属性
Secure 属性がついたクッキーは、HTTPS プロトコル上の暗号化されたリクエストでのみサーバーに送信され、安全でない HTTP では決して送信されないため、中間者攻撃者が簡単にアクセスすることはできません。
- HttpOnly属性
ブラウザ上でJavaScriptのDocument.cookie APIを使用すると、クッキーの値を取得することができます。これによりクロスサイトスクリプティング (XSS) 攻撃によって第三者にクッキー情報を盗み取られる可能性があります。そこで、HttpOnly属性を付与することで、Document.cookie APIの使用を無効にすることができます。
所感
クッキーを使用するときは、どんな情報を設定するか、どんな属性を付与すれば良いか、をしっかり考慮しなければならないと感じました。 特に、ユーザー名、パスワード、クレジットカード、個人情報、金銭に関わる情報などは漏洩する危険性があるので、注意が必要です。 ログイン情報管理おいて、セッションIDを盗まれるいわゆるセッションハイジャックの危険性もあるので、なるべくクッキーでセッションIDを管理しなくても済むようにしたいです。 そういう場合は、Auth0でJWTを使用したりやOpenIDConnectを使用すること優先に考えるべきだと思います。
PrAha Challenge 課題2 「curlとpostmanに慣れる」
こんにちは。最近業務が忙しく、投稿できておりませんでした。 今回はcurlについて学びましたので、紹介していきます。 postmanは別の機会に紹介します。
curlを叩いてみる
まずは、httpbinというサービスを使って、HTTPリクエストの要素(headerやクエリパラメータなど)が返ってくるかどうかを試します。
問題1
- カスタムヘッダーを加える(X-Test='hello')
- methodはGET
入力
curl -H "X-Test : hello" https://httpbin.org/headers
- 出力
{ "headers": { "Accept": "*/*", "Host": "httpbin.org", "User-Agent": "curl/7.64.1", "X-Amzn-Trace-Id": "Root=1-5fe93493-005c489e181254925f733d85", "X-Test": "hello" } }
レスポンスはまずAccepetヘッダに"/"がセットされており、クライアントが全てのメディアタイプを処理できることを示してます。
HostヘッダーはクライアントがリクエストしたURIを示します。これは必須項目です。
続いて、User-agentはクライアントのソフトウェア情報を示します。今回はcurlのバージョン7.64.1を使用しています。
X-Amzn-Trace-IdヘッダはAWSのApplication Load Balancerにて付与されるものです。 おそらくhttps://httpbin.orgがALBを使用しているので、今回付与されいるものと思われます。
"X-Test"は、リクエストする際に自身で付与したヘッダがちゃんと設定できていることが確認できます。
問題2
curl -X POST -H "Content-Type: application/json" -d '{"name":"hoge"}' https://httpbin.org/post
- 出力
{ "args": {}, "data": "{\"name\":\"hoge\"}", "files": {}, "form": {}, "headers": { "Accept": "*/*", "Content-Length": "15", "Content-Type": "application/json", "Host": "httpbin.org", "User-Agent": "curl/7.64.1", "X-Amzn-Trace-Id": "Root=1-5fe93789-33ec03362c93ce62575afb96" }, "json": { "name": "hoge" }, "origin": "103.4.10.234", "url": "https://httpbin.org/post" }
ここで着目すべきヘッダはContent-Typeです。 これはメッセージのボディの内容がどのような種類なのかをメディアタイプで示しております。 ここではapplication/jsonなので、jsonタイプのメッセージをpostします。 "json": {"name": "hoge"}がpostされていることを確認できます。
originは、自身のIPアドレスを示してます。
問題3
{userA: {name: "hoge", age: 29}}をbodyに含めて送信します。
- 入力
curl -X POST -H "Content-Type: application/json" -d '{"userA" : {"name": "hoge", "age": 29}}' https://httpbin.org/post
今回はjsonオブジェクトをpostするので、ヘッダーに"Content-Type: application/json"を付与します。
- 出力
{ "args": {}, "data": "{\"userA\" : {\"name\": \"hoge\", \"age\": 29}}", "files": {}, "form": {}, "headers": { "Accept": "*/*", "Content-Length": "39", "Content-Type": "application/json", "Host": "httpbin.org", "User-Agent": "curl/7.64.1", "X-Amzn-Trace-Id": "Root=1-5fe938a4-3e9f73fb204c55c913d3af71" }, "json": { "userA": { "age": 29, "name": "hoge" } }, "origin": "103.4.10.234", "url": "https://httpbin.org/post" }
入力で付与したオブジェクトが送れていることを確認できました。
問題4
問題2、問題3ではjsonタイプのメッセージを送りましたが、 ここではapplication/x-www-form-urlencodedを指定して送ります。
application/x-www-form-urlencodedとは
キーと値は、その間に '=' がある形でキーと値の組になり、 '&' で区切られてエンコードされる。キーや値の英数字以外の文字は、パーセントエンコーディングされます。 このため、このタイプはバイナリデータを扱うのには向かない。 参考: developer.mozilla.org
URLからパラメータを送る際に使用するエンコードですね。例えば「https://*****.com/hogehoge?name=taro」等 データをpostする際は、基本的にはapplication/jsonが主流で、シンプルなデータを送る際はapplication/x-www-form-urlencodedを使用する認識で良いかと思います。
- 入力
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d '"name=hoge"' https://httpbin.org/post
- 出力
{ "args": {}, "data": "", "files": {}, "form": { "name": "hoge" }, "headers": { "Accept": "*/*", "Content-Length": "9", "Content-Type": "application/x-www-form-urlencoded", "Host": "httpbin.org", "User-Agent": "curl/7.64.1", "X-Amzn-Trace-Id": "Root=1-5fe9419e-4a8c606a47c797c663c96377" }, "json": null, "origin": "103.4.10.234", "url": "https://httpbin.org/post" } formに"name": "hoge"が設定されていることと、"json": nullになっていることを確認できます。 ### 所感 個人開発している方は、あまりhttpヘッダーなど気にした方はいらっしゃらないと思います。 普段使っているwebサイトのhttpヘッダーはどこで見れるの?って思った方、ぜひChromeのデベロッパーツールを使用してみてください。 サイト上で右クリック⇨Inspect⇨Networkタブで見れると思います。 それでは良い開発ライフを!!
PrAha Challenge 課題1 「よく使うHTTPヘッダを理解する」
HTTPヘッダーとは
メッセージのボディに対する付加的な情報、いわゆるメタデータを表す。
課題1(質問)
以下のヘッダーの意味と、役割を説明する
- Host
リクエストしたURIのホスト名とポート番号を示す。 Host ヘッダー項目はすべての HTTP/1.1 リクエストメッセージで送信する必要がある、つまり必須項目である
- Content-type
メッセージのボディの内容がどのような種類なのかをメディアタイプで示す。
例. text image audio
- User-agent
クライアントのソフトウェア情報を示す。
- Accept(コンテントネゴシエーション)
クライアントが自分の処理できるメディアタイプをサーバーに伝える。
リンクをクリックした時、クリック元のURIを示す。
※以下ような場合は、ブラウザーは Referer
ヘッダーを送信しない。
1.参照していたリソースがローカルの "file" または "data" の URI の場合
2. 安全ではない HTTP リクエストが使用されており、それを参照しているページが安全なプロトコル (HTTPS) で受信された場合
- Accept-Encoding
クライアントが認識できる圧縮方式を指定する。
- Authorization
認証する際に使用する認証情報を提示する。
- Location
リダイレクト時の移動先のURI、または新規作成時のURIを示す。
- refererについて
- aタグにtarget="_blank"を設定したところ、先輩エンジニアから「ちゃんとrel=noreferrerを設定した?」と聞かれました。なぜそのような設定が必要なのでしょうか?
- パフォーマンスとセキュリティの問題にさらされるため
- rel=noreferrerを設定しなかった場合に起きうる問題を調べて、説明して下さい
- 先輩エンジニアに「同じオリジンの時はrefererの情報を全部送って、別オリジンの時は、オリジン情報だけをrefererとして送信するように、HTTPリクエストにヘッダを追加しておいてもらえる?」と頼まれました。HTTPリクエストのヘッダーには、どんな値を追加する必要があるでしょうか?
- origin-when-cross-origin
参考: https://wwg.co.jp/blog/3807
https://qiita.com/wakaba@github/items/707d72f97f2862cd8000#relnoreferrer
課題2(クイズ)
- HTTPヘッダーに関するクイズを3問、作成してください
- **以下の意味を教えてください。
- accept: application/json, text/plain, /
- accept-language: en-US,en;q=0.9,ja;q=0.8
- application/x-www-form-urlencoded
所感
リクエストヘッダーやレスポンスヘッダーをDevツール上で見る機会はあったが、それぞれのヘッダーが何を意味しているかを追ったことがなかったので、良い学びになりました。
特にtarget="_blank"はrel=noreferrer
を設定する必要があるとは知利ませんでした。(※現在はブラウザごとにデフォルトで設定されているらしい)
今後は、これらの知識を実装でどのように生かしていけるか、非常に楽しみです。
PrAha Challengeに参加
こんにちは。早いもので2020年もあっという間に終わってしまいました。 現在所属している会社に入社してから1年が経ちまして、悪戦苦闘しながら日々働いております。
ところで最近、とあるベンチャー企業さんが面白いプロジェクトを始めることをTwitterで目にしました。
それが
PrAha Challenge
です。
PrAha Inc.さんが、初級エンジニアを中級エンジニアに育てるプロジェクトを始められました。
これを目にした瞬間、速攻で応募しました。
応募条件は、経験年数が1年以上かつ、いくつかのWEBの基礎知識問題を問きます。 ある程度の点数を獲得し通過し、最後に社長さんとの面談を通過して晴れて第一期生に選ばれます。
第一期生は私を含めて約20~30名です。
何をやるのか
Praha Challengeでやることは、まずWEBの基礎知識を学習し、JavaScriptとフレームワークを使用してテストやフロントエンド、バックエンドを学び、他にもDBの知識、コンテナ、AWS等幅広く学びます。 そして最後にチーム開発を行います。
これらを約半年、もしくはそれ以上の期間で実施します。
課題の進め方
まず大きく4チームに別れます。そしてチームの中で特定の人と2人1組ペアになり、Prahaさんが用意してくれた課題を相方とレビューし合いながら進めます。
分からないところは、チームごとに週100分間メンターに質問できる時間が与えられるので、チームで質問事項をまとめた後メンターと時間を調整する必要があります。
課題を解くだけでなく相方やチームメイトともコミュニケーションを取る必要があるので、技術力だけでなくコミュニケーションスキルも問われます。
さいごに
業務外でこのボリュームをこなすのは正直骨が折れますが、私は遅咲きエンジニアなのでなんとか食らいついていきたいと思います。
今後は、Praha Challengeで学んだことをメインにアウトプットしていきたいと思います!!
自己紹介
初めまして。toshi-oliverと申します。平成元年生まれの29歳です(2019年10月1日時点)
書こう書こうと思いつつズルズルきてしまったので、ここで一念発起して投稿しようと思います。 初回はとりあえず自己紹介ということで、よろしくお願いします。
大学で機械工学を学んだ後、新卒で某プラントメーカーに就職し、フィールドエンジニアとして全国の火力発電所を転々としてました。
その後プログラミングと出会い、2018年5月からtech::expertに通い始め,同年11月から某自社開発系企業に転職しました。
しかし、入社後1ヶ月でCTOは突如辞職しました。原因はなんと、社長との喧嘩別れです...
今後会社としても自社で開発をやっていきたいために、プログラマー志望の私が採用されましたが、CTOが辞めてしまい状況が一気に変わりました。
この会社、自社開発を謳いながら、要件定義、デザイン、開発までほぼ全てアウトソーシング。
そして入社面談で話していたことと、実際の労働条件がどんどん乖離していき、2019年6月いっぱいで退職することにしました。
まぁ前職については色々言いたいことがありますが、この辺でやめておきます笑
そんなこんなで、7月から新たにweb系自社開発企業で研鑽できるよう、ポートフォリオを作成しながら転職を目指しております。