Node.jsでhttpメソッド② PUTとDELETE
前回の続きです。
HTMLのinputタグはPUTとDELETEをサポートしていないため、 XMLHttpRequest を使用します。 https://getbootstrap.jp/
XMLHttpRequestについて
今回はDELETEとPUTメソッドが実際にサーバー側に送信ができているかの
確認のみ行いたいと思います。Google Chromeの検証ツール、Networkを使用。
POSTとPUTとPUTCHの違い
POST
リソースの作成、送信を行う。
PUT
PUTは更新対象のリソースが無い場合は新しく作成する。
更新対象のリソースが存在する場合はすべて置換(更新)を行う。
何度リクエストを繰り返しても同じ結果となる特徴を持っている。
PUTCH
PUTCHは部分的な置換(更新)を行う。
どのような置換(更新)を行うかの選択ができる。
PUTとDELETEのハンズオン
index.js
const http = require('http'); const fs = require('fs'); const hostname = "127.0.0.1"; const port = 3000; const indexhtml = fs.readFileSync('./index.html', 'utf-8'); const sendjs = fs.readFileSync('./send.js', 'utf-8'); const server = http.createServer(function (request, response) { switch (request.url) { case "/": response.end(indexhtml); break; case "/?get=getValue": response.end(indexhtml); break; case "/user": response.end(indexhtml); break; case "/send.js": response.end(sendjs); break; case "/delete": response.end(indexhtml); break; case "/put": response.end(indexhtml); break; default: break; } }); server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); });
send.js
var sendDeleteMethod = document.getElementById('sendDeleteMethod'); sendDeleteMethod.addEventListener('click', function () { var request = new XMLHttpRequest(); request.open("DELETE", "/delete", true); request.send("delete"); }); var sendPutMethod = document.getElementById('sendPutMethod'); sendPutMethod.addEventListener('click', function () { var request = new XMLHttpRequest(); request.open("PUT", "/put", true); request.send("put"); });
new XMLHttpRequest()で生成。
openでメソッドとURLと真偽値で非同期か同期を選択。
sendでサーバー側に送信します。
Deleteボタン押下時はDELETEメソッドを生成後にサーバーへ送信。
Putボタン押下時はPUTメソッドを生成後にサーバーへ送信。
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <form action="/" method="GET"> <input name="get" value="getValue"> <input type="submit" value="GET送信" /> </form> <form action="/user" method="POST"> <input name="post" value="postValue"> <input type="submit" value="POST送信" /> <input type="hidden" name="_method" value="put / delete"> </form> <button id="sendDeleteMethod">delete</button> <button id="sendPutMethod">put</button> <script type="text/javascript" src="./send.js"></script> </body> </html>
値の更新や、削除は次回行う予定。
参考サイト
XMLHttpRequest XMLHttpRequest についてのメモ - Qiita
POST、PUT、PUTCHの違い architecting.hateblo.jp
勉強会⑱
Hands-on and Lightning Talks
開催日時 2021年4月29日(木) 7:00-9:00
本日の発表者は私と、koboriさんとNakagawaさんの3人!
発表者 | テーマ | 資料 | 時間 |
---|---|---|---|
Toku | サーバーとは?Node.jsで立ててみる。 | 発表用資料 | 25分 |
Nakagawa | チーム開発振り返り | 5分 | |
Kobori | dockerでアプリケーションサーバーを起動させる | 20分 |
各テーマの感想
サーバーとは?Node.jsで立ててみる。
GETとPOSTを実装。
DELETEとPUTに関しては後日実装予定。
サーバー間のやりとりについて復習したい。
チーム開発振り返り
1週間の振り返り。
学習コストについて考慮していない。
タスクの粒度が細分化されていない。
その結果、スケジュールが大幅に遅れてしまった。
dockerでアプリケーションサーバーを起動させる
アプリケーションサーバーは問題ないが、DBサーバーを立ち上げるときにエラーとなっていた。
解決方法。
knowledge.sakura.ad.jp
リモートとローカルのストレージがマウンティングしていなかった??
Node.jsでhttpメソッド① GETとPOST
HTTPメソッドとは?
クライアントからサーバーに対して送られる要求のこと。
HTTPメソッドでサーバーに何をしてほしいかを伝えることができる。
メソッドの種類
MDNによると全部で9種類。
developer.mozilla.org
今回は代表的な4つのメソッドについて調べました。
GET、POST、PUT、DELETEこれらの4つのメソッドで
データ操作するうえで基本となるCRUDの性質を満たしています。
まずは4つのメソッドを学んでいきましょう。
メソッド名 | CRUD | 説明 |
---|---|---|
GET | READ | 読み込み |
POST | CREATE | 作成 |
PUT | UPDATE | 更新 |
DELETE | DELETE | 削除 |
GETとPOSTのハンズオン
index.js
const http = require('http'); const fs = require('fs'); const hostname = "127.0.0.1"; const port = 3000; const server = http.createServer(function (request, response) { fs.readFile('./index.html', 'utf-8', readIndex); function readIndex(error, data) { console.log(request.method); console.log(request.url); response.end(data); } }); server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); });
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <form action="/" method="GET"> <input name="get" value="getValue"> <input type="submit" value="GET送信" /> </form> <form action="/" method="POST"> <input name="post" value="postValue"> <input type="submit" value="POST送信" /> </form> </body> </html>
inputボタンを押下時に、サーバー側に送られたRequestを
検証ツールとログに確認を行う。
HTMLのinputタグは、GETとPOSTのみサポートしているため、DELETEとPUTは別の方法を考えたい。
勉強会⑰
Hands-on and Lightning Talks
開催日時 2021年4月24日(土) 7:00-9:00
本日の発表者は私と、koboriさんとNakagawaさんの3人!
発表者 | テーマ | 資料 | 時間 |
---|---|---|---|
Toku | サーバーとは?Node.jsで立ててみる。 | 資料 | 25分 |
Kobori | kintone のJavaScriptカスタマイズをプラグイン化したお話 | 資料 | 20分 |
Nakagawa | 初めてのレビュー | 5分 |
各テーマの感想
kintone のJavaScriptカスタマイズをプラグイン化したお話
- 内容はテーブルにレコードを作成する時の自動化プラグインを作ってみた話。
- マニフェストファイルに設定を記述してnpmからpackage化するモジュールをinstallして、プラグインを作成していく。
- 渡すデータはJSON形式で記述することが多いため、pushではなく、mergeを利用すると良い。
Object.assign()
サーバーとは?Node.jsで立ててみる。
- サーバーって何?
- Node.jsでWEBサーバーを立てる際の動きの確認。
- requestとresponseで何をしているか?
- httpプロトコルの役割等。
初めてのレビュー
- GitHubでのレビューの仕方
- ツールの使い方や、観点など。
- 最終的には褒めることが大事。否定的にならない。
サーバーとは?Node.jsで立ててみる。
サーバーとは?
サーバーはクライアントからの要求(リクエスト)に応じて、何らかのサービス(処理)を提供する側の機能あるいはシステムである。
ja.wikipedia.org
サーバーについて調べて満たしたが、かなり抽象的な言葉だと感じました。
リクエストとレスポンスの話をよく聞きますが、リクエストに対してレスポンス(データを提供)していればコンピューターだけではなくプログラムもサーバーになりうる??
さらに分類していくと、物理サーバーと仮想サーバーに分けられる。
物理サーバー とは?
物理サーバーとは物理的に存在する1台のサーバーのこと。
ハードウェア上で、原則1つのOSを利用する。
仮想サーバー とは?
仮想サーバーとは1台の物理サーバー上で、専用のソフトウェアを使い、複数の仮想的なサーバーを構築すること。
CPUやメモリは物理サーバーのリソースを利用する。分割することで複数のOSと複数のサーバーを動作させることが可能。
サーバーの用途
提供するサービスはサーバーの種類によって異なり、WEBサーバー、メールサーバー、FTPサーバー、DBサーバー、SSHサーバー等がある。
今回はWEBサーバーについてふれていきたい。
WEBサーバーとは?
サーバーの種類の一つで、クライアント(ブラウザ)側からの要求(リクエスト)に対して、文書や画像などをの表示を提供するサーバーのこと。
特徴
- クライアントとサーバーがやり取りを行う際にHTTPという通信プロトコル(ルール)を使用する。
- プロトコル(通信の決まり事)があることで、異なる機器同士のデータ交換を可能としている。
- HTTP(プロトコル)は主にhtmlなどのファイルを送信、受信する際に使う。
Node.jsでWEBサーバーを立ててみる
公式ページのサンプルを参考にしました。
nodejs.org
ハンズオン①
WEBサーバーを立てていきます。
// httpモジュール const http = require('http'); // port番号 const port = 3000; // hostname const hostname = '127.0.0.1' // サーバーを建てる var server = http.createServer(function (request, response) { // requestURLの確認 console.log(request.url); // requestが正常に終了したかの確認 console.log(response.statusCode); // 表示 response.end('hello'); }); // portとipを設定 server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); });
ハンズオン①の結果を見てみる。
ブラウザを立ち上げてURL欄にhttp://127.0.0.1:3000/
を打ち込む。
ちなみに打ち込むURLの説明をすると、httpの部分が通信プロトコル。
127.0.0.1の部分がローカル・ループバック・アドレスと呼ばれ、自分自身のこと。
3000の部分がport番号となります。
request.url
の部分でurl欄に入れたクエリが表示される。
http://127.0.0.1:3000/
の場合だと/
が表示される
response.statusCode
でrequestが成功したことがわかる。(成功レスポンスの200が表示される。
response.end('hello')
ここで文字列をブラウザ側に提供していることがわかる。
ハンズオン②
次はcontentTypeとstatusCodeを指定してみる。
// httpモジュール const http = require('http'); var fs = require('fs'); // port番号 const port = 3000; // hostname const hostname = '127.0.0.1' // サーバーを立てる var server = http.createServer(function (request, response) { // File読込 fs.readFile('./cat.png', function (err, data) { // statusとcontentTypeを指定 response.writeHead(200, { 'Content-Type': 'image/png' }); // 送信後、終了 response.end(data); } ); }) // portとipを設定 server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); });
ハンズオン②の結果を見てみる。
fs.readFile('./cat.png',
にてcat.pngファイル(画像)を読み込んでいます。
response.writeHead(200, { 'Content-Type': 'image/png' });
この箇所でステータスコード200(成功)とContent-Typeを指定してみました。
ブラウザ側に返された情報がどんなものなのかをContent-Typeで伝えています。
参考サイト
httpについて
プロトコル
通信プロトコルのHTTPとは何かわかりやすく解説します! | 押さえておきたいWeb知識
サーバー
勉強会⑯
Hands-on and Lightning Talks
開催日時 2021年4月17日(土) 7:00-9:00
本日の発表者は私と、koboriさん、nakagawaさんの3人!
発表者 | テーマ | 資料 | 時間 |
---|---|---|---|
Toku | SQLインジェクション(Node.js) | 資料 | 25分 |
Kobori | SQLインジェクション(PHP) | 25分 | |
Nakagawa | Notion でチーム開発用に手順書を作ってみた | 5分 |
各テーマの感想
SQLインジェクション(Node.js)
PHPhtmlspecialchars
のような言語特有の実装方法がないか調べたい。
FWを使うことでどのような対策が行われるか?気になる。
SQLインジェクション(PHP)
エスケープ処理でタグを無効化してみるハンズオン。
htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
特殊文字の機能を無効化する。
言語ごとに対策が違うので常に考えながらの実装が必要。
Notion でチーム開発用に手順書を作ってみた
MarkDown形式のDocumentは他にもたくさんあるので他の皆様の選定基準が気になる。
今年中に日本語化されるとのことなので、使ってみたい。
SQLインジェクション
SQLインジェクションとは??
アプリケーションのセキュリティ上の不備を意図的に利用し、アプリケーションが想定しないSQL文を実行させることにより、 データベースシステムを不正に操作する攻撃方法のこと。
代表的な不正操作の例
- ユーザーログイン画面に対して、不正なSQL文を実行しPasswordを取得する。
- 一覧表示画面に不正なSQL文を流しデータの削除を行う。
- データの改竄などを行う。
イメージがつきやすいように実際にやってみましょう。
実際にやってみる
ログインしてみる
ユーザーIdとPasswordが正しければログインできる画面を作成しました。
画面のレイアウトなどから、おそらく検索用のSQLはWHERE Id = '入力値' AND Password = '入力値'
ではないかと予想。
ユーザーId入力フォームに適当な値+セミコロンを入力してみる
1;
ログインすることができました。
なぜログインできる??
;
を入力することでセミコロン以降のSQLを無効にすることができるためIdのみ一致すればログインすることができる。
WHERE Id = '入力値' AND Password = '入力値' → WHERE Id = '入力値'
となる。
そのため適当なIDを打ちこんでもし一致すれば、Passwordなしでログインすることができる。
ログインIdに関しては、ユーザーネームとして使われることもあるため、人目につきやすく見破られやすい。
そのためSQLインジェクションしやすい。
Idがわからないは '' or 1 = 1;
でログインすることができる。
1 = 1の部分が検索条件が真となるためログイン可能。
一度ログイン成功するとセミコロンを利用して他のSQL文も入力できるようになるため、他のテーブルを検索したり、データの改竄や破壊することもできる。
対策を考えてみる
1. 正規表現でセミコロンが1個以上入力された場合のチェックを入れる。
var regix = /;+/;
2. エスケープ処理をする。
エスケープ処理とは、その文字本来の機能とは違う意味を与えるもしくは付与すること。
今回の場合はセミコロンより後ろのSQLを無効化する機能を別の意味に置き換える。
escape()
"@*_+-./"以外を符号化することができる。
developer.mozilla.org
3. プレースホルダーを使う
パラメーター部分を?等の記号で示し、そこへ実際の値を割り当てる。
`SELECT * FROM User WHERE Id = ? AND Password = ?`, [qsdata.id, qsdata.password]
実際にやってみた感想
※DBの種類によっては';'以外でも無効化できるのと他の攻撃方法もたくさん存在するため、これらの対策だけでは万全ではないため安心できない。
以下を参考にさせていただきました。
https://www.nic.ad.jp/ja/materials/iw/2010/proceedings/s3/iw2010-s3-01.pdf
参考サイト
SQLインジェクション
www.amiya.co.jpSQLインジェクションを防ぐ対策とは|わかりやすく仕組みを解説|セキュリティコラム|株式会社網屋
IPA
https://www.ipa.go.jp/files/000017320.pdf
エスケープ
https://wa3.i-3-i.info/word11732.html