2015-09-24 5 views
6

トークンベースの認証を実装するための "Flask Web Development"の本に従っています。基本的には、ユーザーHTTPベーシック認証トークンと彼/彼女自身を認証は、それのために生成されます。Python:危険なAPIトークン生成

s = Serializer(app.config['SECRET_KEY'], expires_in = 3600) 
token = s.dumps({ 'id': user.id }) 

しかし、これは限りidSECRET_KEYが同じまま変化しないように見えます。私はトランザクションがHTTPSを介して行われることを理解していますが、動的トークンがより良いと考えています。どのように動的トークンを達成するには?

答えて

13

時間の影響を受けるトークンが必要な場合は、代わりにTimedSerializer classを使用してください。

>>> from itsdangerous import TimedSerializer 
>>> s = TimedSerializer('sekrit') 
>>> token = s.dumps({'id': 'foobar'}) 
>>> token 
'{"id": "foobar"}.COWWsA.dect1vZLaDdgFQUA1G_iTpPY3Hg' 
>>> s.loads(token, max_age=3600) 
{'id': 'foobar'} 
>>> s.loads(token, max_age=0) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/Users/mpieters/Development/venvs/stackoverflow-2.7/lib/python2.7/site-packages/itsdangerous.py", line 643, in loads 
    .unsign(s, max_age, return_timestamp=True) 
    File "/Users/mpieters/Development/venvs/stackoverflow-2.7/lib/python2.7/site-packages/itsdangerous.py", line 463, in unsign 
    date_signed=self.timestamp_to_datetime(timestamp)) 
itsdangerous.SignatureExpired: Signature age 18 > 0 seconds 

注:またリミットそのタイムスタンプを使用してトークン寿命

だけでなく、それは(したがって新しい署名にあなたがそれを使用するたびに生成)の署名を形成するためにタイムスタンプを使用しないが、あなたのことができSerializer classは実際にexpires_inキーワード引数をサポートしていないので、引用しているコードがTimedJSONWebSignatureSerializerクラスを実際に使用していると思われます(別名でインポートされました)。になります。タイムスタンプも同様:

>>> from itsdangerous import TimedJSONWebSignatureSerializer as Serializer 
>>> s = Serializer('sekrit', expires_in=3600) 
>>> token = s.dumps({'id': 'foobar'}) 
>>> token 
'eyJhbGciOiJIUzI1NiIsImV4cCI6MTQ0MzEwODAyMywiaWF0IjoxNDQzMTA0NDIzfQ.eyJpZCI6ImZvb2JhciJ9.eCD3zKK1lYT8cZ9w8g0YVpaF-1rR-k6UNCYq9dHmvGo' 
>>> s.loads(token) 
{'id': 'foobar'} 
>>> s = Serializer('sekrit', expires_in=0) 
>>> token = s.dumps({'id': 'foobar'}) 
>>> token 
'eyJhbGciOiJIUzI1NiIsImV4cCI6MTQ0MzEwNDUwMCwiaWF0IjoxNDQzMTA0NTAwfQ.eyJpZCI6ImZvb2JhciJ9.Eiw3Eco7p61X-ikMxXS5dDVmjYmRSThcsMCxMyuA-r0' 
>>> s.loads(token) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/Users/mpieters/Development/venvs/stackoverflow-2.7/lib/python2.7/site-packages/itsdangerous.py", line 807, in loads 
    date_signed=self.get_issue_date(header)) 
itsdangerous.SignatureExpired: Signature expired 

タイムスタンプが含まれているので、生成されたトークンは、ない静的である:

>>> s = Serializer('sekrit', expires_in=3600) 
>>> token1 = s.dumps({'id': 'foobar'}) 
>>> token2 = s.dumps({'id': 'foobar'}) 
>>> from difflib import ndiff 
>>> print '\n'.join(ndiff(token1.split('.'), token2.split('.'))) 
- eyJhbGciOiJIUzI1NiIsImV4cCI6MTQ0MzEwODIwMywiaWF0IjoxNDQzMTA0NjAzfQ 
?          ^^     ^^ 

+ eyJhbGciOiJIUzI1NiIsImV4cCI6MTQ0MzEwODIxMSwiaWF0IjoxNDQzMTA0NjExfQ 
?          ^^     ^^ 

    eyJpZCI6ImZvb2JhciJ9 
- YmrKQTvZEWw4_JOOPn5uEk9QlZNla4o3Gvo09H1MXfM 
+ ApeLrwT_R60pkvCYe4ihzJFPG55tGiJK6VSi6BKxAXM 

これら2つのトークンは、それらが同じシリアライザによって生成されたにもかかわらず、著しく異なります。

+0

スポットオン。エイリアスだった。ありがとう! – lang2

関連する問題