Web

[Python] BottleでBasic認証を実装する方法

BottleでBasic認証を実装するには、requestオブジェクトを使用してHTTPヘッダーから認証情報を取得し、ユーザー名とパスワードを検証します。

request.authで認証情報を取得し、base64でデコードしてユーザー名とパスワードを確認します。

認証に失敗した場合は、responseにステータスコード401を設定し、WWW-Authenticateヘッダーを追加して再度認証を要求します。

BottleフレームワークでのBasic認証の概要

Basic認証とは?

Basic認証は、HTTPプロトコルを使用したシンプルな認証方式です。

ユーザー名とパスワードを組み合わせて、リクエストヘッダーに含めて送信します。

サーバー側では、受け取った認証情報を検証し、正しければリソースへのアクセスを許可します。

この方式は実装が簡単ですが、セキュリティ上のリスクがあるため、HTTPSと併用することが推奨されます。

Bottleフレームワークの特徴

Bottleは、Pythonで書かれた軽量なWebフレームワークです。

以下のような特徴があります。

特徴説明
軽量シンプルで小さなコードベースを持つ。
シングルファイルすべての機能が1つのファイルに収まる。
プラグイン対応必要に応じて機能を追加できる。
シンプルなルーティングURLと関数を簡単にマッピングできる。

Bottleでの認証の基本的な流れ

BottleでBasic認証を実装する際の基本的な流れは以下の通りです。

  1. クライアントがリソースにアクセスを試みる。
  2. サーバーは認証情報を要求するレスポンスを返す。
  3. クライアントはユーザー名とパスワードを含むリクエストを送信する。
  4. サーバーは受け取った認証情報を検証する。
  5. 認証が成功すれば、リソースへのアクセスを許可する。

Basic認証が必要なシチュエーション

Basic認証が必要となるシチュエーションには以下のようなものがあります。

シチュエーション説明
管理者用ダッシュボード管理者のみがアクセスできるページ。
APIの保護特定のAPIエンドポイントへのアクセス制限。
機密情報の表示ユーザーの個人情報や機密データの保護。

BottleでBasic認証を実装する手順

Bottleのインストール方法

BottleはPythonのパッケージとして提供されているため、pipを使用して簡単にインストールできます。

以下のコマンドを実行してください。

pip install bottle

このコマンドを実行することで、Bottleフレームワークがインストールされます。

Basic認証に必要なモジュールのインポート

Basic認証を実装するためには、Bottleフレームワークと、認証情報を処理するためのモジュールをインポートする必要があります。

以下のコードを参考にしてください。

from bottle import Bottle, request, response
import base64

このコードでは、Bottleの主要な機能と、Base64エンコーディングを扱うためのbase64モジュールをインポートしています。

認証情報の取得方法

クライアントから送信された認証情報は、リクエストヘッダーのAuthorizationフィールドに含まれています。

以下のコードで、認証情報を取得する方法を示します。

def get_auth_info():
    auth_header = request.get_header('Authorization')
    if auth_header and auth_header.startswith('Basic '):
        return auth_header.split(' ')[1]
    return None

この関数は、AuthorizationヘッダーからBasic認証の情報を取得し、Base64エンコードされた部分を返します。

認証情報のデコードと検証

取得した認証情報はBase64でエンコードされているため、デコードしてユーザー名とパスワードを取得します。

以下のコードを参考にしてください。

def validate_auth(auth_info):
    decoded_info = base64.b64decode(auth_info).decode('utf-8')
    username, password = decoded_info.split(':')
    # ここでユーザー名とパスワードを検証する
    return username == 'admin' and password == 'password'

この関数では、デコードした情報をユーザー名とパスワードに分割し、正しい組み合わせかどうかを検証します。

認証失敗時のレスポンス設定

認証に失敗した場合、サーバーは401 Unauthorizedレスポンスを返す必要があります。

以下のコードでその処理を示します。

def unauthorized_response():
    response.status = 401
    response.headers['WWW-Authenticate'] = 'Basic realm="Access to the staging site"'
    return "認証に失敗しました。"

この関数は、認証失敗時に適切なレスポンスを設定します。

認証成功時の処理

認証が成功した場合、リクエストを処理するための関数を呼び出します。

以下のコードを参考にしてください。

def success_response():
    return "認証に成功しました!"

この関数は、認証が成功したことを示すメッセージを返します。

これをルートハンドラーに組み込むことで、認証が成功した際の処理を実装できます。

Basic認証のセキュリティ強化

HTTPSを使用する理由

Basic認証は、ユーザー名とパスワードをBase64エンコードして送信しますが、これは暗号化されていないため、ネットワーク上で簡単に傍受される可能性があります。

HTTPS(HTTP Secure)を使用することで、通信がSSL/TLSで暗号化され、データが安全に送信されます。

これにより、以下のようなメリットがあります。

  • データの盗聴防止: 通信内容が暗号化されるため、第三者による盗聴を防げます。
  • データの改ざん防止: データが送信中に改ざんされるリスクを低減します。
  • 信頼性の向上: HTTPSを使用することで、ユーザーに対して安全なサイトであることを示すことができます。

パスワードのハッシュ化

パスワードを平文で保存することは非常に危険です。

万が一データベースが侵害された場合、攻撃者はすぐにユーザーのパスワードを知ることができます。

これを防ぐために、パスワードはハッシュ化して保存することが推奨されます。

以下のように、Pythonのhashlibモジュールを使用してパスワードをハッシュ化できます。

import hashlib
def hash_password(password):
    return hashlib.sha256(password.encode()).hexdigest()

この関数は、SHA-256アルゴリズムを使用してパスワードをハッシュ化し、ハッシュ値を返します。

認証情報の保存方法

認証情報は安全に保存する必要があります。

以下の方法が一般的です。

保存方法説明
データベースハッシュ化したパスワードをデータベースに保存。
環境変数環境変数に認証情報を保存し、アプリケーションから参照。
設定ファイル設定ファイルにハッシュ化したパスワードを保存。ただし、アクセス制限が必要。

これらの方法を組み合わせることで、認証情報の安全性を高めることができます。

認証情報の再利用を防ぐ方法

認証情報の再利用を防ぐためには、以下の対策が有効です。

  • セッション管理: 認証後にセッションを生成し、セッションIDを使用してユーザーを識別します。

これにより、毎回のリクエストで認証情報を送信する必要がなくなります。

  • トークンベース認証: JWT(JSON Web Token)などのトークンを使用して、認証情報を一時的に保持します。

トークンは一定の期間で無効化されるため、再利用を防げます。

  • 定期的なパスワード変更: ユーザーに定期的にパスワードを変更させることで、万が一の情報漏洩時のリスクを軽減します。

これらの対策を講じることで、Basic認証のセキュリティを強化することができます。

BottleでのBasic認証の応用例

特定のルートにのみBasic認証を適用する方法

Bottleでは、特定のルートにのみBasic認証を適用することができます。

以下のコードは、特定のエンドポイントに対して認証を実装する方法を示しています。

from bottle import Bottle, request, response, run
app = Bottle()
def basic_auth():
    auth_info = get_auth_info()
    if not auth_info or not validate_auth(auth_info):
        return unauthorized_response()
@app.route('/protected')
@basic_auth
def protected():
    return "このページは保護されています。"
@app.route('/public')
def public():
    return "このページは誰でもアクセスできます。"
run(app, host='localhost', port=8080)

この例では、/protectedルートにのみBasic認証を適用し、/publicルートは誰でもアクセスできるようにしています。

複数ユーザーの認証を実装する方法

複数のユーザーを認証する場合、ユーザー名とパスワードの組み合わせを辞書やデータベースで管理します。

以下のコードは、複数ユーザーの認証を実装する方法を示しています。

users = {
    'user1': 'password1',
    'user2': 'password2',
}
def validate_auth(auth_info):
    decoded_info = base64.b64decode(auth_info).decode('utf-8')
    username, password = decoded_info.split(':')
    return username in users and users[username] == password

このコードでは、users辞書に複数のユーザー情報を格納し、認証時にその情報を検証します。

認証情報をデータベースで管理する方法

認証情報をデータベースで管理することで、ユーザーの追加や削除が容易になります。

以下は、SQLiteを使用して認証情報を管理する例です。

import sqlite3
def create_user_table():
    conn = sqlite3.connect('users.db')
    c = conn.cursor()
    c.execute('''CREATE TABLE IF NOT EXISTS users (username TEXT, password TEXT)''')
    conn.commit()
    conn.close()
def add_user(username, password):
    conn = sqlite3.connect('users.db')
    c = conn.cursor()
    c.execute("INSERT INTO users (username, password) VALUES (?, ?)", (username, hash_password(password)))
    conn.commit()
    conn.close()

このコードでは、SQLiteデータベースにユーザー情報を保存するためのテーブルを作成し、新しいユーザーを追加する関数を定義しています。

トークンベース認証との併用

Basic認証とトークンベース認証を併用することで、セキュリティをさらに強化できます。

以下は、JWTを使用したトークンベース認証の実装例です。

import jwt
import datetime
SECRET_KEY = 'your_secret_key'
def generate_token(username):
    payload = {
        'username': username,
        'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=30)
    }
    return jwt.encode(payload, SECRET_KEY, algorithm='HS256')
def decode_token(token):
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256'])
        return payload['username']
    except jwt.ExpiredSignatureError:
        return None

このコードでは、ユーザー名を含むJWTトークンを生成し、トークンをデコードしてユーザー名を取得する関数を定義しています。

Basic認証と組み合わせることで、より安全な認証システムを構築できます。

まとめ

この記事では、Bottleフレームワークを使用したBasic認証の実装方法やセキュリティ強化の手法、応用例について詳しく解説しました。

Basic認証はシンプルで実装が容易ですが、セキュリティリスクを考慮し、適切な対策を講じることが重要です。

これを機に、実際のプロジェクトにBasic認証を取り入れ、セキュリティを強化するための実践を始めてみてはいかがでしょうか。

関連記事

Back to top button
目次へ