0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

django-rest-knox ライブラリのトークンのtoken_key について

Posted at

トークンを生成し、トークンの登録を確認

"token": "e2db80303283ee15f102789e2e7f5a4053cb774041b385a83eeab19fc6298aee"

token_key は検索用のインデックスであり、ハッシュ化されていないトークンの頭文字8文字である

先ほど発行したトークンの頭文字8文字と一致していることを確認

token_key: e2db8030

knox model の説明

knox.models.py

class AbstractAuthToken(models.Model):

    objects = AuthTokenManager()

    digest = models.CharField(
        max_length=CONSTANTS.DIGEST_LENGTH, primary_key=True)
    token_key = models.CharField(
        max_length=CONSTANTS.MAXIMUM_TOKEN_PREFIX_LENGTH +
        CONSTANTS.TOKEN_KEY_LENGTH,
        db_index=True
    )
    user = models.ForeignKey(User, null=False, blank=False,
                             related_name='auth_token_set', on_delete=models.CASCADE)
    created = models.DateTimeField(auto_now_add=True)
    expiry = models.DateTimeField(null=True, blank=True)

    class Meta:
        abstract = True

    def __str__(self) -> str:
        return f'{self.digest} : {self.user}'


class AuthToken(AbstractAuthToken):
    class Meta:
        swappable = 'KNOX_TOKEN_MODEL'

それぞれのフィールドについて詳しく説明させていただきます:

1. digest

digest = models.CharField(max_length=CONSTANTS.DIGEST_LENGTH, primary_key=True)
  • トークンのハッシュ値を保存するフィールドです
  • primary_key=Trueで主キーとして設定されています
  • セキュリティのため、実際のトークン値ではなく、ハッシュ化された値を保存します
  • CharFieldとして定義され、長さはCONSTANTS.DIGEST_LENGTHで制限されています

2. token_key

token_key = models.CharField(
    max_length=CONSTANTS.MAXIMUM_TOKEN_PREFIX_LENGTH + CONSTANTS.TOKEN_KEY_LENGTH,
    db_index=True
)
  • トークンの識別子部分を保存するフィールドです
  • db_index=Trueでインデックスが作成され、検索を高速化します
  • 最大長はMAXIMUM_TOKEN_PREFIX_LENGTHTOKEN_KEY_LENGTHの合計です
  • トークンの一部を保存することで、完全な照合の前に高速なフィルタリングが可能になります

3. user

user = models.ForeignKey(User, null=False, blank=False,
                        related_name='auth_token_set', 
                        on_delete=models.CASCADE)
  • トークンの所有者であるユーザーへの外部キー参照です
  • null=False, blank=Falseで必須フィールドとして設定されています
  • related_name='auth_token_set'により、ユーザーモデルからauth_token_setでトークンにアクセス可能です
  • on_delete=models.CASCADEでユーザーが削除された場合、関連するトークンも削除されます

4. created

created = models.DateTimeField(auto_now_add=True)
  • トークンが作成された日時を自動的に記録します
  • auto_now_add=Trueにより、レコード作成時に自動的に現在時刻が設定されます

5. expiry

expiry = models.DateTimeField(null=True, blank=True)
  • トークンの有効期限を設定するフィールドです
  • null=True, blank=Trueで任意フィールドとして設定されています
  • 値が設定されている場合、その日時でトークンは無効になります

このモデルはAbstractAuthTokenとして抽象クラスで定義され、実際の実装はAuthTokenクラスで行われています。swappable = 'KNOX_TOKEN_MODEL'の設定により、必要に応じて独自のトークンモデルに置き換えることが可能です。

knox.models.py
class AuthTokenManager(models.Manager):
    def create(
        self,
        user,
        expiry=knox_settings.TOKEN_TTL,
        prefix=knox_settings.TOKEN_PREFIX,
        **kwargs
    ):
        token = prefix + crypto.create_token_string()
        digest = crypto.hash_token(token)
        if expiry is not None:
            expiry = timezone.now() + expiry
        instance = super().create(
            token_key=token[:CONSTANTS.TOKEN_KEY_LENGTH], digest=digest,
            user=user, expiry=expiry, **kwargs)
        return instance, token


これはDjango Knoxライブラリの認証トークンを作成するためのマネージャークラスです。詳しく説明させていただきます:

AuthTokenManagerの機能説明

def create(self, user, expiry=knox_settings.TOKEN_TTL, prefix=knox_settings.TOKEN_PREFIX, **kwargs):

このメソッドは以下の主要なパラメータを受け取ります:

  • user: トークンを発行するユーザー
  • expiry: トークンの有効期限(デフォルトはknox_settings.TOKEN_TTL
  • prefix: トークン文字列の接頭辞(デフォルトはknox_settings.TOKEN_PREFIX

処理の流れ

  1. トークンの生成:
token = prefix + crypto.create_token_string()
  • 設定された接頭辞と、暗号学的に安全な乱数文字列を組み合わせて新しいトークンを生成します
  1. ダイジェストの作成:
digest = crypto.hash_token(token)
  • セキュリティのため、トークンをハッシュ化します
  • このハッシュ値がデータベースに保存されます
  1. 有効期限の設定:
if expiry is not None:
    expiry = timezone.now() + expiry
  • 有効期限が指定されている場合、現在時刻に指定された期間を加算します
  1. トークンインスタンスの作成:
instance = super().create(
    token_key=token[:CONSTANTS.TOKEN_KEY_LENGTH],
    digest=digest,
    user=user,
    expiry=expiry,
    **kwargs
)
  • データベースにトークン情報を保存します
  • token_keyには完全なトークンの一部のみを保存(検索用)
  • digestにはトークン全体のハッシュ値を保存
  • ユーザーと有効期限情報も保存
  1. 戻り値:
return instance, token
  • データベースに保存されたトークンインスタンスと
  • クライアントに送信する生のトークン文字列を返します

セキュリティ上の特徴

  • 完全なトークン文字列はデータベースに保存されません
  • データベースには検索用の部分文字列(token_key)とハッシュ値(digest)のみが保存されます
  • トークンの検証時には、受け取ったトークンをハッシュ化して保存されているダイジェストと比較します

参考文献:

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?