概要(やりたいこと含む)
ふと、Webサーバの認証でよく利用されるアクセストークンをpythonで生成するにはどうしたらいいんやろうと思って調べてみました。
アクセストークンについては、ご存知の方が多いかもしれませんが、
わかりやすく説明されていると感じたものを紹介しておきます。
生成方法
調べたところ、どうやらpython3.6より前は特にそういうモジュールはなさそう
(調査不足かもしれませんので、ご存知の方がいらっしゃればぜひコメントお願いします)
Python 3.6にてsecrets
というモジュールが標準で利用できるようになったらしいです。
16進数のランダムな文字列(≒アクセストークン)を生成するにはsecrets.token_hex
を利用すればよいとのこと。
引数にバイト数を指定できるが、2017年12月17日時点では、32 バイト (256 ビット)が生成される模様
(ドキュメントによればこのデフォルト値は変更する可能性があるとのことです)
import secrets
token = secrets.token_hex()
print(token) # 7fca54bac0f3d2bbd6e4b493dec45366ea2fb7f884e8ac97f13c40fd00cc4e5f などが出力される(デフォルト256bit)
文字列(トークン)同士の比較は、secrets.compare_digest
を利用すればよいとのこと。
なお、このメソッドではタイミング攻撃と呼ばれるリスクを減らす方法で比較を行うみたいなので、普通に==
よりもこちらを利用するのがよさげです。
import copy
import secrets
token1 = secrets.token_hex()
token2 = copy.deepcopy(token1)
token3 = secrets.token_hex()
print(secrets.compare_digest(token1, token2)) #True
print(secrets.compare_digest(token2, token3)) #False
パスワードリセットなどで一時的なURLを生成する場合は、secrets.token_urlsafe
を利用すればよいとのこと
import secrets
url = 'https://mydomain.com/reset=' + secrets.token_urlsafe()
print(url) # https://mydomain.com/reset=Gc5CzVbf6f-zu9Mr5fpRtTBeQQCK00blasM7EWtrSis などが出力される
所感
アクセストークンについてもなんとなくは理解してましたが、ちゃんと調べてなかったので、いい勉強になりました。あと、タイミング攻撃という言葉も恥ずかしながら初めて知った...。
ふと気になったことを調べて、知らない知識が増えてなんか得した感じがしました(笑)