0

私は現在、RESTfulAPIのhttp呼び出しを自動化するコンパイラ用のPython言語プラグインを作成しています。ソケットモジュールとSSLモジュールを使用してログイン/認証を機能させることができましたが、この低レベルのアプローチでは、認証トークンとシークレットを取得するために応答を解析する際に潜在的な問題が発生するようです。リクエストモジュールは人気があり効率的ですが、特定の認証ニーズに対して適切に機能させることができないようです。Javaプラグインの認証に使用した.jksファイルから変換した.pemファイル(公開鍵のみを含む)の形式のトラストストアを使用しています。サーバーは、ユーザー名とパスワードがjson形式でリクエスト本文に送信されることを想定しています。これが私が使おうとしているコードです:

#Server and login data
...
host = 'localhost'
port = 8443
pem_file = "C:\\Users\\aharasta\\pycert.pem"

#Digest password with MD5 algorithm
m = hashlib.md5()
m.update(password)
encrypted_password = m.hexdigest()

url = <url>
data = {'userid': user_name, 'password': encrypted_password}
json_data = json.dumps(data)
headers = {'Content-type': 'application/json', 'Accept': 'text/plain', 'Content \                     
          Length': len(json_data)} 

r = requests.post(url, headers = headers, data = json_data, cert = pem_file)
print(r)

このコードを実行すると、「証明書の検証に失敗しました」というSSLエラーが発生します。パラメータverify = Falseまたはを追加するverify = pem_fileと、サーバーから404応答を受け取ります。また、サーバーをデバッグモードで起動し、(検証パラメーターの1つを使用して)要求を実行すると、サーバーの認証方法やその他の方法に到達しないことにも注意してください。この問題に関する洞察や助けをいただければ幸いです。

4

1 に答える 1

1

まず、投稿内容にいくつか問題があります。

  • 指定hostしますportが、例は示しませんurl。そのため、テストにローカルデプロイメントを使用していると推測でき、サーバーへのリクエストを実際に表示できます。話している方法はわかりませんが、サーバー開発にFlaskに似たものを使用している場合は、認証をJSONエンコードされたデータとして送信したくない場合があります。理由のための認証ヘッダーがあり、要求には理由のための認証ハンドラーがあります。;-)

  • Content-Lengthヘッダーを自分で指定しないでください。リクエストはあなたのためにこれを行います。それを超えて、あなたはそれを間違って指定しているので(あなたが投稿したものに従って)、404はあなたのサーバーが認識しないヘッダーを受信することからである可能性があります。

ここで、を指定する理由はないはずです。またはverify=Falseを指定できます。どちらかまたは両方で問題ないはずですが、決して使用しないでください。cert=pem_fileverify=pem_fileverify=False

最後に、発生したのSSLErrorは、提供しているpemファイルがサーバーが指定しているファイルと一致していないことを示しています。そのことを念頭に置いて、ローカルサーバーの設定を確認することをお勧めします。リクエストは証明書の検証自体を処理しませんが、urllib3はそれを提供します。ご提供いただいたパラメータに基づいて設定します。そして、これがurllib3のせいではないかと思います。SSLErrorこれは、標準ライブラリのsslモジュールから発生するを発生させるからです。

編集

説明は、無効なファイルを指定しているドキュメントにあります。これを正しく行うには、を使用する必要があります。*.pemcertverify='/path/to/file.pem'

編集#2

すでに送信されたリクエストを検査するには、次のようにします。

r = requests.post(...)
r.request
# PreparedRequest('POST', url, ...)
r.request.body
r.request.headers
# etc.

送信する前にリクエストを変更するには、次のようにします。

from requests import Request, Session

s = Session()
r = Request('POST', url, datajson_data, headers=headers)
p = r.prepare()
p.body = 'New body'
p.headers = #etc.
s.send(p, verify=pem_file)
于 2013-02-05T15:51:24.100 に答える