J'essaie d'utiliser l'OAuth d'un site Web, qui requiert que la méthode de signature soit uniquement 'HMAC-SHA1'.
Je me demande comment implémenter cela en Python?
Pseudocodish:
def sign_request():
from hashlib import sha1
import hmac
# key = b"CONSUMER_SECRET&" #If you dont have a token yet
key = b"CONSUMER_SECRET&TOKEN_SECRET"
# The Base String as specified here:
raw = b"BASE_STRING" # as specified by OAuth
hashed = hmac.new(key, raw, sha1)
# The signature
return hashed.digest().encode("base64").rstrip('\n')
Les erreurs de signature résident généralement dans la chaîne de base, assurez-vous de bien comprendre cela (comme indiqué par la spécification OAuth1.0: http://tools.ietf.org/html/draft-hammer-oauth-10#section- 3.4.1 ).
Les entrées suivantes sont utilisées pour générer la chaîne de base de signature:
Paramètres, par ordre alphabétique, tels que (sauts de ligne pour la lisibilité):
file=vacation.jpg
&oauth_consumer_key=dpf43f3p2l4k3l03
&oauth_nonce=kllo9940pd9333jh
&oauth_signature_method=HMAC-SHA1
&oauth_timestamp=1191242096
&oauth_token=nnch734d00sl2jdk
&oauth_version=1.0
&size=original
Concaténer et URL encoder chaque partie et il se termine comme:
GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26
oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26
oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1191242096%26
oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal
Pour l'amour de Dieu, si vous faites quelque chose avec oauth, utilisez la bibliothèque requests
pour Python! J'ai essayé d'implémenter HMAC-SHA1 à l'aide de la bibliothèque hmac
en Python et c'est un casse-tête, d'essayer de créer la chaîne de base correcte oauth, etc. Il suffit d'utiliser des demandes et c'est aussi simple que:
>>> import requests
>>> from requests_oauthlib import OAuth1
>>> url = 'https://api.Twitter.com/1.1/account/verify_credentials.json'
>>> auth = OAuth1('YOUR_APP_KEY', 'YOUR_APP_SECRET', 'USER_OAUTH_TOKEN', 'USER_OAUTH_TOKEN_SECRET')
>>> requests.get(url, auth=auth)
C'est déjà là Keyed-Hashing for Message Authentication
Enfin, voici une solution qui fonctionne (testée avec Python 3) et qui utilise oauthlib .
J'utilise la première étape OAuth donnée à titre d'exemple dans le document officiel RTF 1 :
Client Identifier: dpf43f3p2l4k3l03
Client Shared-Secret: kd94hf93k423kf44
POST /initiate HTTP/1.1
Host: photos.example.net
Authorization: OAuth realm="Photos",
oauth_consumer_key="dpf43f3p2l4k3l03",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="137131200",
oauth_nonce="wIjqoS",
oauth_callback="http%3A%2F%2Fprinter.example.com%2Fready",
oauth_signature="74KNZJeDHnMBp0EMJ9ZHt%2FXKycU%3D"
La valeur de oauth_signature
correspond à ce que nous aimerions calculer.
Ce qui suit définit ce que nous voulons signer:
# There is no query string present.
# In case of http://example.org/api?a=1&b=2 - the value
# would be "a=1&b=2".
uri_query=""
# The oauthlib function 'collect_parameters' automatically
# ignores irrelevant header items like 'Content-Type' or
# 'oauth_signature' in the 'Authorization' section.
headers={
"Authorization": (
'OAuth realm="Photos", '
'oauth_nonce="wIjqoS", '
'oauth_timestamp="137131200", '
'oauth_consumer_key="dpf43f3p2l4k3l03", '
'oauth_signature_method="HMAC-SHA1", '
'oauth_callback="http://printer.example.com/ready"'
)
}
# There's no POST data here - in case it was: x=1 and y=2,
# then the value would be '[("x","1"),("y","2")]'.
data=[]
# This is the above specified client secret which we need
# for calculating the signature.
client_secret="kd94hf93k423kf44"
Et c'est reparti:
import oauthlib.oauth1.rfc5849.signature as oauth
params = oauth.collect_parameters(
uri_query="",
body=data,
headers=headers,
exclude_oauth_signature=True,
with_realm=False
)
norm_params = oauth.normalize_parameters(params)
base_string = oauth.construct_base_string(
"POST",
"https://photos.example.net/initiate",
norm_params
)
sig = oauth.sign_hmac_sha1(
base_string,
client_secret,
'' # resource_owner_secret - not used
)
from urllib.parse import quote_plus
print(sig)
# 74KNZJeDHnMBp0EMJ9ZHt/XKycU=
print(quote_plus(sig))
# 74KNZJeDHnMBp0EMJ9ZHt%2FXKycU%3D
Il existe plusieurs bibliothèques python disponibles sur le site Web oauth , mais si vous êtes simplement intéressé par une implémentation spécifique, vous pouvez consulter l'une d'elles .
Dans Python 3.7, il existe un moyen optimisé de le faire. HMAC (clé, msg, digest) .digest () utilise une implémentation optimisée en C ou en ligne, qui est plus rapide pour les messages stockés dans la mémoire.
Renvoie le résumé de msg pour la clé secrète donnée et le résumé. La fonction est équivalent à HMAC (clé, msg, digérer) .digest (), mais utilise un C .__ optimisé. ou une implémentation en ligne, ce qui est plus rapide pour les messages qui entrent dans Mémoire. Les paramètres key, msg et digest ont la même signification que dans new ().
Détail d'implémentation CPython, l'implémentation C optimisée est seulement utilisé lorsque digest est une chaîne et le nom d'un algorithme de digest, qui est supporté par OpenSSL.
Vous pouvez essayer la méthode suivante.
def _hmac_sha1(input_str):
raw = input_str.encode("utf-8")
key = 'your_key'.encode('utf-8')
hashed = hmac.new(key, raw, hashlib.sha1)
return base64.encodebytes(hashed.digest()).decode('utf-8')