メインコンテンツまでスキップ

HTTP プロトコルの『GET』解説


この記事では、HTTP プロトコルにおける主要な操作である『GET』について解説します。

GETの概要や使用例、使用ケースについて説明し、C# を使用した具体的なコード例も示します。
クライアント側とサーバー側の両方についてコーディング例を記載しておりますので、参考にしてください。

購読対象層
  • 対象者: .NET 開発者やWebアプリケーション開発者。
  • 記事概要: GETの基本的な概念と具体的な使用例、セキュリティに関連する重要な話題について詳述します。
  • 技術: GETを学び始めたばかりの初心者から、その知識を実際のプロジェクトに応用したい方まで。

関連する解説シリーズ記事一覧

タイトルとリンク概要説明
1. HTTP プロトコルの基本解説HTTP プロトコルの基本的な概要や使い方についての解説です。
2. HTTP GET メソッドの解説本記事です。
3. HTTP POST メソッドの解説HTTP POST メソッドの解説です。
4. HTTP PUT メソッドの解説HTTP PUT メソッドの解説です。
5. HTTP DELETE メソッドの解説HTTP DELETE メソッドの解説です。

動作環境情報

.NETバージョン
  • .NET Core: すべてのバージョン(1.0 以降)
  • .NET Framework: 4.5 以降
  • .NET Standard: 1.1 以降(ただし、2.0 が推奨されます)
必要なサードパーティー製パッケージ

この記事で必須となるサードパーティー製パッケージはありません。
しかし Swagger(Swashbuckle.AspNetCore) は API の開発やデバッグで役に立つため、導入の検討を推奨します。



1. GETとは

GETは、指定されたリソースから情報を取得するために使用されます。
これは、サーバーからクライアント(例えば、Webブラウザ)へデータを送信する一方的なプロセスです。

GETは、データをサーバーに送るのではなく、サーバーからデータを取得するために設計されています。

GETは冪等性(Idempotency)であるため、同じリクエストを何度実行しても同じ結果になります。

一般的なGETシーケンスは、以下の通りです:

冪等性(Idempotency)

HTTPメソッドの「冪等性」は、同一の操作を何度実行してもシステムの状態が最初の1回目の操作以降変わらないことを意味します。
つまり、同じリクエストを繰り返し送信しても、リソースの状態に対して同じ効果が適用され、それ以上の変更が発生しない性質です。

より詳しい解説は 基本解説の冪等性セクション を参照してください。

簡単に覚える:要約ワンポイント

GETは、サーバーからデータを取得する。冪等である。

1.1. GETを使うケース

GETは主に、以下のようなシナリオで使用されます:

  • Webページの閲覧: ユーザーがWebページをリクエストするとき、ブラウザはそのページのコンテンツを取得するためにGETリクエストを送信します。
  • 画像や動画などのメディアファイルの取得: Webサイト上のメディアファイルを表示する際にもGETリクエストが用いられます。
  • APIを通じたデータの取得: RESTful APIでは、特定のデータセットを取得するためにGETリクエストがよく使用されます。

一般的なWebアプリケーションでは、以下のようなデータ取得の例があります:

  • ユーザーデータの取得
  • 商品一覧の取得
  • 記事やニュースフィードの取得


2. セキュリティ上の考慮事項

GETはデータを取得する際に使用され、クエリパラメータとしてデータがURLに含まれます。
これにはいくつかのセキュリティリスクが伴います。

2.1. 主なGETのセキュリティリスク

  • データの漏洩:
    GETリクエストはURLにパラメータを含むため、機密情報がログやリファラーヘッダーに残り漏洩する可能性があります。
  • クロスサイトリクエストフォージェリ(CSRF):
    GETリクエストはサーバーの状態を変更すべきでないが、誤って重要な動作に使われることがあり、不正なサイトから意図しないリクエストが発行されるリスクがあります。
  • キャッシュによるリスク:
    敏感な情報を含むGETリクエストがブラウザやプロキシサーバーにキャッシュされると、不正アクセスにより情報が漏れる可能性があります。

2.2. セキュリティ対策

これらの対策を実施することで、GETメソッドを使用した際のリスクを大幅に低減できます。

  • HTTPSの使用:
    すべての通信をHTTPSを通じて暗号化し、データの盗聴や改ざんを防ぎます。
  • 機密情報のGETパラメータ使用回避:
    機密性の高い情報はGETリクエストのパラメータに含めず、POSTリクエストやHTTPヘッダーで送信する方法を検討します。
  • 適切なキャッシュコントロールヘッダーの使用:
    キャッシュコントロールHTTPヘッダーを適切に設定して、敏感な情報がキャッシュされないようにします。
  • CSRF対策の実施:
    GETリクエストを利用したCSRF攻撃を防ぐため、重要な操作はPOSTリクエストで行うようにし、トークンやリファラチェックを利用してCSRF対策を強化します。
HTTPSの重要性

HTTPSは すべてのクライアントとサーバー間の通信を暗号化 するため、データの盗聴や改ざんを防ぐことができます。

HTTPSの全文とセキュリティについては、内部ページである HTTP プロトコルの基本解説 にも詳細な解説を記載しています。

攻撃について

脆弱性の攻撃に対する詳細はGET解説セクションから外れるため、ここでは詳細な説明を省略します。

参考: wikipedia - クロスサイトリクエストフォージェリ

2.3. GET に含めるべきではない情報

上記のセキュリティリスクを踏まえ、GETのパラメータに含めるべきではない情報の例を以下に示します:

  • パスワード
  • クレジットカード情報
  • セッションID
  • トークン
  • センシティブな個人情報
  • 重要と分類する機密情報
他にもたくさんあります

これらの情報以外にも、セキュリティ上のリスクを軽減するためにGETリクエストに含めるべきでない情報は多数あります。
プロジェクトでよく精査を行い、適切に情報を扱うように心がけて下さい。



3. GETの使用例 (C#)

C#でのGETの使用例を以下に示します。

前提:サンプルソースコードは「わかりやすさ」を重視しています

サンプルコードは "できるだけ短く" かつ "わかりやすい" を重視しています。参考にして利用する場合、適切にカスタマイズをして下さい。
具体的には、以下のような部分です:

  • パラメータのハードコーディング
  • エラーハンドリングの簡略化
  • セキュリティ対策の簡略化

3.1. 基本的な使用例 (全データの取得)

最初に、最も単純なパラメータ不要パターンのGETリクエストを実行する例を示します。

GET-ALL-使用ユーザー側-クライアントの例(C#)

[C#] GetUserAll.razor
@page "/get-user-all"
@rendermode InteractiveServer
@inject HttpClient httpClient

<h3> api/user/all - ユーザーリストを取得 </h3>

<button class="btn btn-primary" @onclick="FetchUsers">Get User List</button>

<div class="content">
@if (UserList.Count == 0)
{
<p>ユーザーが見つかりませんでした。</p>
}
else
{
<ul>
@foreach (var user in UserList)
{
<li>@user</li>
}
</ul>
}
</div>

@code {
private readonly List<string> UserList = new List<string>();

// `Get User List` ボタンがクリックされたときに呼び出されるメソッド
private async Task FetchUsers()
{
UserList.Clear();

// GET リクエストを送信し UserController からユーザー情報を取得
var users = await httpClient.GetFromJsonAsync<IEnumerable<string>>("api/user/all");
if (users is not null)
{
UserList.AddRange(users);
}
}
}

Blazor では、HttpClient クラスを使用してGETリクエストを送信し、サーバーからデータを取得します。

FetchUsers メソッドは、ボタンがクリックされたときに呼び出され、api/user/all にGETリクエストを送信してユーザーリストを取得します。
HttpClient は、BlazorのDI(Dependency Injection)機能を使用して注入され、接続先サーバーを環境毎に切り替えることができます。


GET-ALL-サーバー側-コントローラーの例(C#)

[C#] ProductsController.cs
using Microsoft.AspNetCore.Mvc;

namespace Ateliers.Lectures.MVC.APIServer.Controllers
{
[ApiController]
[Route("API/[controller]")]
public class UserController : ControllerBase
{
// 仮のユーザーデータをリストとして保持
private static readonly List<string> _UserList = new List<string>
{
"Alice", "Bob", "Charlie"
};

// GET: api/user/all
[HttpGet("All")]
public ActionResult<IEnumerable<string>> GetUsers()
{
// ユーザー情報を確認して、ユーザーリストかエラーを返す
return _UserList.Any()
? Ok(_UserList.Select(user => $"ID:{_UserList.IndexOf(user)}, USER:{user}"))
: NotFound("ユーザーは0件です。");
}
}
}

.NET 8 の Web API では、[HttpGet] アトリビュートを使用してGETリクエストを処理するエンドポイントを指定します。

GetUsers メソッドは、api/user/all にGETリクエストが送信されたときに呼び出され、ユーザーリストを返します。

Routeアトリビュート

7行目に定義されているコントローラーのアトリビュート [Route] は、リクエストを処理するエンドポイントを指定します。
例えば [Route("hoge/hogehoge/[controller]")] に変更すると
クライアント側は https://example.com/hoge/hogehoge/user/all にアクセスすることで GetUsers() が呼び出されます。

プレースホルダー

[Route] アトリビュートの中で指定されている [controller] は、コントローラー名を自動的に置き換えるプレースホルダーです。
この例では、クラス名である UserControllerUser に置き換えられます。
このプレースホルダーを使用する API は、コントローラー名を変更しても、ルーティングの変更が不要になりますが
コントローラーのクラス名には気を配る必要があります。

GET-ユーザーリスト-シーケンス図

概要:

  1. ユーザーは、アプリケーションでボタンをクリックしてユーザーリストを取得しようとします。
  2. アプリケーションは、サーバーに対してGETリクエストを送信します。
  3. サーバーは、リクエストを処理し、ユーザーリストのJSONレスポンスを返します。
  4. アプリケーションは、JSONレスポンスを解析し、ユーザーリストを表示します。

3.2. 基本的な使用例 (特定データの取得)

パラメータを使い、特定のデータを取得するGETリクエストの例を示します。

GET-ById-使用ユーザー側-クライアントの例(C#)

[C#] GetUserById.razor
@page "/get-user-by-id"
@rendermode InteractiveServer
@inject HttpClient httpClient

<h3> api/get/{id} - 特定ユーザーの取得 </h3>

<div>
<label for="userId">Enter User ID:</label>
<InputNumber @bind-Value="UserId" id="userId" min="0" />
<button @onclick="FetchUser">Get User Info</button>
</div>

@if (IsLoading)
{
<p>Loading...</p>
}
else if (!string.IsNullOrEmpty(UserInfo))
{
<p><strong>User Info:</strong> @UserInfo</p>
}
else if (HasError)
{
<p style="color:red">Error: @ErrorMessage</p>
}

@code {
// 画面にバインドされているユーザーID
private int UserId;

private bool IsLoading;
private bool HasError;
private string? UserInfo;
private string? ErrorMessage;

// `Get User Info` ボタンがクリックされたときに呼び出されるメソッド
private async Task FetchUser()
{
IsLoading = true;
HasError = false;
UserInfo = null;
ErrorMessage = null;

try
{
// GET リクエストを送信し UserController からユーザー情報を取得
var response = await httpClient.GetAsync($"api/user/{UserId}");

if (response.IsSuccessStatusCode)
{
UserInfo = await response.Content.ReadAsStringAsync();
}
else
{
HasError = true;
ErrorMessage = await response.Content.ReadAsStringAsync();
}
}
catch (Exception ex)
{
HasError = true;
ErrorMessage = ex.Message;
}
finally
{
IsLoading = false;
}
}
}

Blazor では、HttpClient クラスを使用してGETリクエストを送信し、サーバーからデータを取得します。

FetchUser メソッドは、ボタンがクリックされたときに呼び出され、api/user/{id} にGETリクエストを送信して特定のユーザー情報を取得します。

UserId は、ユーザーが入力したIDを保持するための変数です。
この変数は、InputNumber コンポーネントを使用してユーザーが入力した値をバインドします。

HttpClient は、BlazorのDI(Dependency Injection)機能を使用して注入され、接続先サーバーを環境毎に切り替えることができます。

GET-ById-サーバー側-コントローラーの例(C#)

[C#] UserController.cs
using Microsoft.AspNetCore.Mvc;

namespace Ateliers.Lectures.MVC.APIServer.Controllers
{
[ApiController]
[Route("API/[controller]")]
public class UserController : ControllerBase
{
// 仮のユーザーデータをリストとして保持
private static readonly List<string> _UserList = new List<string>
{
"Alice", "Bob", "Charlie"
};

// GET: api/user/{id}
[HttpGet("{id}")]
public ActionResult<string> GetUserById(int id)
{
// ユーザー情報を確認して、ユーザー情報かエラーを返す
return id < 0 || id >= _UserList.Count
? NotFound("ユーザーが見つかりません")
: Ok(_UserList[id]);
}
}
}

.NET 8 の Web API では、[HttpGet] アトリビュートを使用してGETリクエストを処理するエンドポイントを指定します。

GetUserById メソッドは、api/user/{id} にGETリクエストが送信されたときに呼び出され、特定のユーザー情報を返します。

id は、クライアントから送信されたユーザーIDを受け取るための引数です。

プレースホルダー

[HttpGet("{id}")] の中で指定されている {id} は、クライアントから送信されたリクエストURLの一部を表します。
例えば api/user/99 にアクセスすると、id には、数値 99 が渡されます。

引数は文字列型など、他の型も使用可能です

この例では int 型の引数を使用していますが、string 型など他の型を使用することも可能です。
例えば追加で [HttpGet("ByName/{name}")] を実装することで、ユーザー名を指定してユーザー情報を取得することが可能になります。
その場合、URLは api/user/byname/Alice のようになり、引数は string name として受け取ります。

GET-ユーザー情報-シーケンス図

概要:

  1. ユーザーは、特定のユーザーIDを使ってユーザー情報を取得しようとします。
  2. アプリケーションは、指定されたユーザーIDでGETリクエストを送信します。
  3. サーバーは、リクエストを処理します。
    ユーザーが存在する場合は、ユーザー情報のJSONレスポンスを返し、存在しない場合は404エラーメッセージを返します。
  4. アプリケーションは、レスポンスを解析し、ユーザー情報かエラーメッセージを表示します。


参考文献リンクなど

HTTPについて:

リンク説明
wikipedia - HTTPSHTTPSについてのWikipediaの記事
wikipedia - HTTPステータスコードHTTPステータスコードについてのWikipediaの記事

セキュリティ:

リンク説明
wikipedia - クロスサイトリクエストフォージェリCSRFについてのWikipediaの記事

フィードバックの提供方法と連絡先

連絡先

この記事に関するフィードバックやご質問、ご意見がございましたら プロフィールページの連絡先 からお気軽にご連絡ください。
貴重なディスカッションをお待ちしております。