目次
7.3 クロスサイトスクリプティング攻撃 (XSS) の防止
コラム紹介
コラム購読アドレス:https://blog.csdn.net/qq_35831906/category_12375510.html
1 ネットワークプログラミングの基礎
ネットワーク プログラミングとは、コンピューター ネットワークを使用して、異なるコンピューター間でデータを交換し、通信するプロセスを指します。基盤となるデータ伝送やプロトコルの対話から高レベルのアプリケーション開発まで、複数のレベルをカバーします。
プロトコル:プロトコルは、コンピューターの通信方法を指定する一連のルールと標準です。ネットワーク通信は、送信者と受信者の間でデータが正しく転送されるように、特定のプロトコルに従う必要があります。一般的なネットワーク プロトコルには、TCP、UDP、HTTP、HTTPS、FTP、SMTP などが含まれます。
IP アドレス: IP アドレスは、ネットワーク上のコンピュータとデバイスを識別するために使用される一意のアドレスです。IP アドレスは、IPv4 と IPv6 の 2 つのバージョンに分かれています。IPv4 アドレスは、ドットで区切られた 4 つの 10 進数字で構成されます (例: 192.168.0.1)。一方、IPv6 アドレスは、より長い 16 進数字の文字列を使用します。
ポート番号:ポート番号は、コンピュータ上のさまざまなアプリケーションの通信チャネルを識別するために使用されます。IP アドレスには複数のポートを含めることができ、各ポートはアプリケーションに対応します。ポート番号は、0 ~ 65535 の範囲の 16 ビット整数です。
ソケット:ソケットはネットワーク通信の基本的な操作インターフェイスであり、コンピュータ間の接続を確立し、データを送信するために使用されます。ソケットには IP アドレス、プロトコル、ポート番号が含まれており、これらを介して異なるコンピューター間の通信を実現できます。
クライアントとサーバー:クライアントはネットワーク要求を開始するコンピューターまたはアプリケーションであり、サーバーはこれらの要求を受信して処理するコンピューターまたはアプリケーションです。クライアントがリクエストを送信すると、サーバーが応答して対応するサービスを提供します。
HTTP (ハイパーテキスト転送プロトコル): HTTP は、Web 上でデータを転送するために使用されるプロトコルであり、クライアント/サーバー モデルに基づいています。クライアントは HTTP リクエストを送信し、サーバーは HTTP レスポンスを返します。HTTP は、GET、POST、PUT、DELETE およびその他のリクエスト メソッドをサポートします。
TCP (伝送制御プロトコル): TCP は、信頼性の高いデータ伝送とエラー チェックを提供する接続指向のプロトコルです。TCP は、接続の確立、データのセグメント化、および再構成によって、データが損失なく順序どおりに送信されることを保証します。
UDP (ユーザー データグラム プロトコル): UDP は、データ送信の信頼性とエラー チェックを提供しないコネクションレス型プロトコルですが、より高速です。UDP は、音声やビデオの送信などのリアルタイム通信に適しています。
パケット:データはネットワーク上でパケットの形式で送信されます。各パケットには、送信元 IP アドレス、宛先 IP アドレス、ポート番号などのデータに関する情報が含まれています。パケットは、送信中に断片化、並べ替え、または再送信される可能性があります。
ドメイン名:ドメイン名は、Web サイトまたはサーバーを識別する人間が判読できる URL です。ドメイン名は DNS を通じて IP アドレスに解決されるため、ユーザーは覚えやすいドメイン名を使用して Web サイトにアクセスできます。
DNS (ドメイン ネーム システム): DNS は、コンピュータがインターネット上の他のコンピュータを見つけられるように、ドメイン名を IP アドレスにマッピングする分散データベース システムです。これにより、人間が読めるドメイン名を使用してリソースにアクセスできるようになります。
ネットワーク プログラミングは現代のコンピューターの世界で重要な役割を果たしており、インターネット、Web アプリケーション、リアルタイム通信、分散システムなどの多くの分野をサポートしています。
2. 基本概念とプロトコル
2.1 コンピュータネットワークの基礎
コンピュータ ネットワークは、リソースと情報を共有するために通信リンクを通じて相互に接続された複数のコンピュータとデバイスの集合です。ネットワークは、ローカル エリア ネットワーク (LAN)、ワイド エリア ネットワーク (WAN)、インターネットなどに分類できます。ネットワークは、リモート通信、リソース共有、データ送信などの機能を提供します。
2.2 ネットワークプロトコル、IPアドレス、ポート番号
- ネットワーク プロトコル:ネットワーク プロトコルは、コンピューター間の通信を管理する一連の規則と標準です。データ形式、通信プロセス、エラー処理などを定義します。一般的なネットワーク プロトコルには、TCP、UDP、HTTP、HTTPS、FTP、SMTP などが含まれます。
- IP アドレス (インターネット プロトコル アドレス): IP アドレスは、ネットワーク上のコンピュータとデバイスを一意に識別するために使用されます。IPv4 は 32 ビットの 2 進数 (例: 192.168.0.1) を使用しますが、IPv6 は 128 ビットの 16 進数を使用します。
- ポート番号:ポート番号は、コンピュータ上のさまざまなアプリケーションの通信チャネルを識別するために使用されます。0 ~ 65535 の範囲の 16 ビット整数です。TCP と UDP はポート番号を使用して、データを適切なアプリケーションに配信します。
2.3 一般的なネットワークプロトコル
TCP (伝送制御プロトコル): TCP は、信頼性の高いデータ伝送とエラー検出を提供する接続指向のプロトコルです。データを小さな断片(データセグメント)に切り分けて送信し、確実にデータが届くようにするため、ファイル転送やメールなど重要なデータの送信に適しています。
UDP (ユーザー データグラム プロトコル): UDP は、信頼性とエラー検出を提供しないコネクションレス型プロトコルです。データをデータグラムに分割して送信するため、音声や動画の送信、オンラインゲームなどのリアルタイム通信に適しています。
HTTP (ハイパーテキスト転送プロトコル): HTTP は、Web ページなどのハイパーテキスト ドキュメントを Web 上で転送するために使用されます。これは、クライアントがリクエストを送信し、サーバーが応答を返すステートレス プロトコルです。HTTP は、ブラウザと Web サーバー間の通信に一般的に使用されます。
HTTPS (Hypertext Transfer Protocol Secure): HTTPS は、SSL/TLS プロトコルを介して通信を暗号化し、データのプライバシーと整合性を保護する暗号化された HTTP プロトコルです。オンライン支払いや機密データの送信など、安全な Web 通信に使用されます。
3. ソケットプログラミング
ソケットプログラミングはネットワークプログラミングの中核であり、コンピュータ間のデータ転送や通信を実現するために使用されます。ソケットの基本的な概念、動作、通信モデルと方法については、以下で詳しく説明します。
3.1 ソケットの基本概念
ソケットは、異なるコンピューター間でデータを交換できる抽象的な通信エンドポイントです。ソケットは、ターゲット IP アドレス、プロトコル、ポート番号などの情報を含むネットワーク通信の基本インターフェイスを提供します。ソケットは一般に、ストリーム ソケット (TCP) とデータグラム ソケット (UDP) の 2 つのタイプに分類されます。
3.2 ソケットの基本操作
接続の作成、バインド、リスニング、受け入れが含まれます。
ソケットの作成:ライブラリを使用してsocket
ソケットを作成します。アドレス ファミリ (IPv4 または IPv6) とソケット タイプ (TCP または UDP) を指定して、対応するタイプのソケットを作成します。
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建TCP套接字
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 创建UDP套接字
バインド アドレス:クライアントが接続できるように、サーバー ソケットを IP アドレスとポート番号にバインドする必要があります。通常、クライアント ソケットにはバインドは必要ありません。
server_address = ('127.0.0.1', 12345)
server_socket.bind(server_address)
接続のリスニング:サーバーソケットの場合、listen()
接続リクエストを受け入れる準備をするためにメソッドを呼び出す必要があります。
server_socket.listen(5) # 允许同时等待5个连接请求
接続を受け入れる:サーバーソケットは、accept()
このメソッドを使用してクライアントの接続要求を受け入れ、クライアントと通信するための新しいソケットを返します。
client_socket, client_address = server_socket.accept()
3.3 ソケット通信モデルとメソッド: send、recv
ソケット通信モデルは、データの送受信に基づいています。TCP 通信では、通常、send()
メソッドを使用してデータを送信し、次にrecv()
メソッドを使用してデータを受信します。UDP 通信では、sendto()
データの送信にメソッドが使用され、recvfrom()
データの受信にメソッドが使用されます。
3.3.1 TCP通信モデル
サービスターミナル:
client_socket, client_address = server_socket.accept()
data = client_socket.recv(1024) # 接收数据
client_socket.send(b"Hello, client!") # 发送数据
クライアント:
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('127.0.0.1', 12345))
client_socket.send(b"Hello, server!") # 发送数据
data = client_socket.recv(1024) # 接收数据
3.3.2 UDP通信モデル
サービスターミナル:
data, client_address = server_socket.recvfrom(1024) # 接收数据
server_socket.sendto(b"Hello, client!", client_address) # 发送数据
クライアント:
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client_socket.sendto(b"Hello, server!", ('127.0.0.1', 12345)) # 发送数据
data, server_address = client_socket.recvfrom(1024) # 接收数据
ソケットの基本概念、操作、通信モデルを理解することで、TCP または UDP ベースのクライアントやサーバーなどの単純なネットワーク通信アプリケーションの構築を開始できます。学習が深まるにつれて、リアルタイム通信、ネットワーク セキュリティ、その他の分野など、より複雑なネットワーク アプリケーションに拡張できます。
4. クライアントサーバーモデル
クライアント/サーバー モデルは、ネットワーク プログラミングにおける一般的な通信パターンであり、クライアントがリクエストを開始し、サーバーがリクエストを受信してサービスを提供します。クライアントはサーバーにリクエストを送信し、サーバーの応答を待ちます。以下に、クライアントとサーバーの役割、それらがどのように対話するか、および簡単な通信の作成例について説明します。
4.1 クライアントの役割
クライアントとは、サービスを要求する当事者です。サーバーにリクエストを送信し、サーバーの応答を待ちます。クライアントは通常、Web ブラウザ、モバイル アプリケーション、チャット クライアントなど、エンド ユーザーが使用するアプリケーションです。
4.2 サーバーの役割
サーバーはサービスを提供する当事者です。クライアントのリクエストを受信し、処理して、応答を返します。サーバーは通常、Web ページ、データ ストレージ、リアルタイム通信などのさまざまなサービスを提供するために、高性能コンピューター上で実行されます。
4.3 クライアントとサーバーの対話
一般的なクライアントとサーバーの対話には、次の手順が含まれます。
- クライアントは接続リクエストを開始します。
- サーバーは接続リクエストを受け入れ、リクエストを処理するためのスレッドまたはプロセスを割り当てます。
- クライアントはリクエスト データをサーバーに送信します。
- サーバーはリクエストを処理し、応答データをクライアントに返します。
- クライアントはサーバーの応答を受信し、応答データを処理します。
4.4 単純なクライアントとサーバーの通信例を作成します。
以下は、Python の Socket ライブラリを使用して、単純な TCP クライアントとサーバーの通信を作成する例です。この例では、クライアントはサーバーにメッセージを送信し、サーバーはメッセージを受信して確認応答を返します。
サービスターミナル:
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('127.0.0.1', 12345))
server_socket.listen(5)
print("Server listening...")
while True:
client_socket, client_address = server_socket.accept()
print(f"Connected to {client_address}")
data = client_socket.recv(1024)
print("Received:", data.decode())
response = "Message received!"
client_socket.send(response.encode())
client_socket.close()
クライアント:
import socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('127.0.0.1', 12345))
message = "Hello, server!"
client_socket.send(message.encode())
response = client_socket.recv(1024)
print("Server response:", response.decode())
client_socket.close()
この例では、サーバーは接続要求をリッスンし、クライアント接続を受け入れ、クライアントからメッセージを受信します。サーバーはメッセージを処理した後、確認応答をクライアントに送信します。クライアントはサーバーに接続し、メッセージを送信し、サーバーから応答を受け取ります。これは、単純なクライアント/サーバー通信プロセスを示しています。
5. WebSocket プログラミング
WebSocket は、全二重双方向通信を実現するために設計された TCP ベースのプロトコルで、クライアントが最初にリクエストを開始する必要がなく、サーバーがクライアントにアクティブにデータをプッシュできるようにします。WebSocket は、リアルタイム アプリケーション、チャット アプリケーション、リアルタイム通知などのシナリオで非常に役立ちます。
5.1 WebSocketのプロトコルと特徴
- WebSocket は、HTTP での頻繁な接続と切断を回避するために、単一の長い接続を使用します。
- クライアントとサーバーはいつでもデータを送信して、リアルタイム通信を実現できます。
- プロトコル自体は、追加のポーリングなしで双方向通信をサポートします。
- ブラウザとサーバー間のリアルタイムの対話に適しています。
5.2 サードパーティのライブラリを使用して WebSocket 通信を実装する
websockets
は、WebSocket 通信を実装するための人気のある Python ライブラリです。websockets
以下は、ライブラリを使用して WebSocket サーバーとクライアントを作成する例です。
WebSocketサーバー:
import asyncio
import websockets
async def echo(websocket, path):
async for message in websocket:
await websocket.send(message)
start_server = websockets.serve(echo, "127.0.0.1", 8765)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
WebSocketクライアント:
import asyncio
import websockets
async def hello():
uri = "ws://localhost:8765"
async with websockets.connect(uri) as websocket:
await websocket.send("Hello, WebSocket!")
response = await websocket.recv()
print(response)
asyncio.get_event_loop().run_until_complete(hello())
この例では、WebSocket サーバーがリッスンし、
ws://localhost:8765
クライアントが接続してメッセージを送信すると、サーバーは同じメッセージをクライアントに送り返します。クライアントはサーバーに接続した後、メッセージを送信し、サーバーの応答を待ちます。このライブラリを使用すると
websockets
、リアルタイムの双方向ネットワーク アプリケーションを構築するための WebSocket 通信を簡単に実装できます。これにより、ライブ チャット、リアルタイム更新、リアルタイム監視などのアプリケーション シナリオが容易になります。
6. 非同期プログラミングとマルチスレッド
6.1 非同期プログラミングの概念と利点
非同期プログラミングは、I/O 集中型のタスクを処理するように設計されたプログラミング パターンであり、プログラムはプロセス全体をブロックするのではなく、I/O 操作が完了するのを待ちながら他のタスクの実行を継続できます。非同期プログラミングでは、プログラムが I/O を待機している間に他のタスクを実行できるため、プログラムの同時実行性と応答性を向上させることができます。
非同期プログラミングの主な利点は次のとおりです。
- ノンブロッキング: 非同期プログラミングにより、プログラムはプロセス全体をブロックすることなく、I/O を待機している間も他のタスクの実行を継続できます。
- 高い同時実行性:複数のタスクを同時に実行できるため、プログラムの同時実行パフォーマンスが向上します。
- 応答性の向上:プログラムは、I/O を待機している間に他のタスクを実行できるため、ビジー状態でも応答性を維持できます。
6.2 asyncio ライブラリを使用して非同期ネットワーク プログラミングを実装する
asyncio
これは、非同期コードを作成するための Python の非同期 I/O フレームワークです。asyncio
以下は、ライブラリを使用して非同期ネットワーク プログラミングを実装する例です。
import asyncio
async def main():
await asyncio.gather(fetch_url("https://example.com"), fetch_url("https://google.com"))
async def fetch_url(url):
print(f"Fetching {url}")
await asyncio.sleep(2)
print(f"Fetched {url}")
asyncio.run(main())
この例では、2 つの
fetch_url
コルーチンが同時に異なる URL に対して非同期リクエストを作成します。そうすることでawait asyncio.gather()
、非同期を利用して同時に実行できます。
6.3 スレッド ライブラリを使用してマルチスレッド ネットワーク プログラミングを実装する
threading
これは、複数のスレッドを作成および管理するために使用できる Python 用のスレッド管理ライブラリです。threading
以下は、ライブラリを使用してマルチスレッド ネットワーク プログラミングを実装する例です。
import threading
import requests
def fetch_url(url):
print(f"Fetching {url}")
response = requests.get(url)
print(f"Fetched {url}")
thread1 = threading.Thread(target=fetch_url, args=("https://example.com",))
thread2 = threading.Thread(target=fetch_url, args=("https://google.com",))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print("Threads completed")
この例では、2 つのスレッドが異なる URL に対して同時にリクエストを行います。各スレッドは
requests
ライブラリを使用して HTTP リクエストを送信します。これらの例の非同期およびマルチスレッド コードは、非同期プログラミングとマルチスレッドの基本概念を示すために、主に同時実行に焦点を当てていることに注意してください。実際のアプリケーションでは、さらにエラー処理、同期、リソース共有、その他の問題に対処する必要がある場合があります。
7. データのセキュリティと暗号化
ネットワーク プログラミングのセキュリティと防御は、ネットワーク通信とアプリケーションを悪意のある攻撃、データ漏洩、その他のセキュリティ脅威から確実に保護するために重要な側面です。以下は、ネットワーク プログラミングのセキュリティと防御の詳細な説明と例です。
7.1 データの暗号化とプライバシー保護
暗号化アルゴリズムを使用して、送信中のデータのプライバシーを保護します。SSL/TLS プロトコルは、ネットワーク通信に暗号化層を提供し、送信中にデータが簡単に盗まれたり改ざんされたりしないようにします。
例: Python のssl
ライブラリを使用してネットワーク接続に SSL 暗号化を追加する
import ssl
import socket
context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
with socket.create_connection(('example.com', 443)) as client_socket:
with context.wrap_socket(client_socket, server_hostname='example.com') as secure_socket:
secure_socket.send(b'Hello, server!')
response = secure_socket.recv(1024)
7.2 入力の検証とフィルタリング
クライアントから受信した入力は常に検証され、悪意のある入力や攻撃を防ぐためにフィルタリングされます。
例: Django Web フレームワークからの入力検証の使用。
from django import forms
class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput)
7.3 クロスサイトスクリプティング攻撃 (XSS) の防止
XSS 攻撃を防ぐために、未検証のユーザー入力をページに直接挿入しないでください。入力フィルタリングとエンコードを使用して、出力のセキュリティを確保します。
例: Flask フレームワークの関数を使用して、escape
XSS 攻撃を防ぎます。
from flask import Flask, escape
app = Flask(__name__)
@app.route('/hello')
def hello():
name = request.args.get('name', '')
safe_name = escape(name)
return f'Hello, {safe_name}!'
7.4 SQL インジェクションの防止
SQL インジェクション攻撃を防ぐには、パラメーター化されたクエリまたは ORM (オブジェクト リレーショナル マッピング) ライブラリを使用します。ユーザー入力を SQL クエリに直接接続しないでください。
例: SQLAlchemy を使用したパラメータ化されたクエリ。
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
engine = create_engine('sqlite:///mydatabase.db')
Session = sessionmaker(bind=engine)
session = Session()
username = "admin' OR '1'='1"
user = session.query(User).filter_by(username=username).first()
7.5 セキュリティ更新とバグ修正
最新のセキュリティ修正を入手するために使用するライブラリとフレームワークを定期的に更新してください。脆弱性の通知を監視し、既知のセキュリティ脆弱性に迅速に対応します。
例: コマンドを使用して Python ライブラリを更新します。
pip install --upgrade package-name
8. 認証と認可
8.1 ユーザー ID 認証の方法と技術
ユーザー認証は、ユーザーが誰であるかを判断して、要求されたリソースにアクセスする権限をユーザーが持っていることを確認するプロセスです。一般的な認証方法には次のものがあります。
- ユーザー名とパスワード:ユーザーは検証のためにユーザー名とパスワードを提供します。パスワードは、多くの場合、ハッシュ化およびソルティング技術を使用して保護する必要があります。
- 多要素認証 (MFA):ユーザーは、セキュリティを強化するために、パスワード、携帯電話認証コード、指紋などの複数の認証要素を提供します。
- シングル サインオン (SSO):ユーザーは一度ログインすると、関連付けられた複数のアプリケーションにアクセスできるため、資格情報を何度も入力する必要がなくなります。
- ソーシャル メディア ログイン:ユーザーは、Google、Facebook などのソーシャル メディア アカウントを使用してログインできます。
- 証明書:ユーザーは、認証と暗号化通信に使用されるデジタル証明書を持っています。
8.2 ユーザーログインとアクセス制御の実装
許可されたユーザーのみが機密データまたは機能にアクセスできるようにします。認証 (ユーザーの ID の検証) と認可 (アクセス権の割り当て) を使用して、アクセスを制限します。
- ユーザー ログイン: ユーザーは ID 情報 (ユーザー名/パスワードなど) を提供し、サーバーは ID 情報を検証し、その後のアクセスのための資格情報としてトークンを提供します。
- アクセス制御: セッションやトークンなどのメカニズムを使用して、ユーザーが承認されたリソースのみにアクセスできるようにし、未承認のリソースへのアクセスを拒否します。
例: Flask-Login ライブラリを使用したユーザー認証の実装。
from flask import Flask, render_template
from flask_login import LoginManager, login_required
app = Flask(__name__)
login_manager = LoginManager(app)
@app.route('/profile')
@login_required
def profile():
return render_template('profile.html')
8.3 JWTを使用した認証
JSON Web Token (JWT) は、2 つのエンティティ間で情報を安全に送信するためのオープン スタンダードです。これは、ヘッダー、ペイロード、署名の 3 つの部分で構成されます。JWT は、認証と認可によく使用されます。
- ヘッダー:トークンのタイプと署名アルゴリズムを指定します。
- ペイロード:ユーザー ID、ロールなどのユーザー関連情報が含まれます。
- 署名:ヘッダーとペイロードにキーで署名することで、トークンの整合性を確保します。
例: Python のライブラリを使用してPyJWT
JWT トークンを作成および検証します。
import jwt
import datetime
# 创建JWT令牌
payload = {"user_id": 123, "exp": datetime.datetime.utcnow() + datetime.timedelta(days=1)}
secret_key = "secret_key"
token = jwt.encode(payload, secret_key, algorithm="HS256")
print("Token:", token)
# 验证JWT令牌
try:
decoded_payload = jwt.decode(token, secret_key, algorithms=["HS256"])
print("Decoded Payload:", decoded_payload)
except jwt.ExpiredSignatureError:
print("Token expired")
except jwt.InvalidTokenError:
print("Invalid token")
JWT を使用すると、安全なユーザー認証とアクセス制御を実装し、セッション状態をサーバーに保存することを回避できるため、サーバーの負荷が軽減されます。