2016-06-22 21 views
3

私はPythonでいくつかのREST APIを書こうとしていますが、まずAuthenticate codeを書き始めました。 、私はを通じてこのURLを呼び出すようにしようとしています今安全なPython REST API

@app.route('/student/<studentid>', methods = ['GET']) 
@requires_auth 
def api_users(studentid): 
    students = {'1':'ABC', '2':'XYZ', '3':'TEST'} 

    if studentid in students: 
     return jsonify({studentid:students[studentid]}) 
    else: 
     return not_found() 

:私は私のサンプルアプリケーションを確保するために上記のコード部分を使用している

from functools import wraps 
from flask import request, Response 

def check_auth(username, password): 
    """This function is called to check if a username/
    password combination is valid. 
    """ 
    return username == 'admin' and password == 'secret' 

def authenticate(): 
    """Sends a 401 response that enables basic auth""" 
    return Response(
    'Could not verify your access level for that URL.\n' 
    'You have to login with proper credentials', 401, 
    {'WWW-Authenticate': 'Basic realm="Login Required"'}) 

def requires_auth(f): 
    @wraps(f) 
    def decorated(*args, **kwargs): 
     auth = request.authorization 
     if not auth or not check_auth(username, password): 
      return authenticate() 
     return f(*args, **kwargs) 
    return decorated 

:私は、サイトの1に認証のためのサンプルコードを見つけましたpythonリクエスト/ pycurlモジュール。しかし、毎回有効なユーザー名/パスワードに関係なく401エラーを返します。

使用して要求:カールを使用して

import requests, base64 
usrPass = "admin:secret" 
b64Val = base64.b64encode(usrPass) 
from requests.auth import HTTPBasicAuth 
from requests.packages.urllib3.exceptions import InsecureRequestWarning 
requests.packages.urllib3.disable_warnings(InsecureRequestWarning) 
res = requests.get('https://<abc.com>/student/1', auth=HTTPBasicAuth('admin','secret'), headers={'Authorization': 'Basic %s' % b64Val}, data={}, verify=False) 
print res 

:毎回それが401エラーを返す理由

myCurlPut = pycurl.Curl() 
myCurlPut.setopt(pycurl.URL, "https://<abc.com>/student/1") 
myCurlPut.setopt(pycurl.HTTPAUTH, pycurl.HTTPAUTH_BASIC) 
myCurlPut.setopt(pycurl.USERPWD, "%s:%s" % ('admin', 'secret')) 
myCurlPut.setopt(pycurl.SSL_VERIFYPEER, 0) 
myCurlPut.setopt(pycurl.HTTPHEADER, ['X-HTTP-Method-Override: GET']) 
myCurlPut.perform() 

は、誰も私を助けてください。提案してください。

+0

デバッグ出力を@ requires_auth @に入れようとしましたか?あなたがリクエストをしたときに 'request.authorization'の価値は何ですか? –

+0

request.authorizationの値はNoneとなっています – user1138143

答えて

1

:だからとしてrequires_auth目的球を変更してみてください。

from functools import wraps 

from flask import Flask,Response,request, abort 


app = Flask(__name__) 

def check_auth(name,passw): 
    return (name=='admin' and passw=='pass') 

def requires_auth(f): 
    @wraps(f) 
    def decorated(*args, **kwargs): 
     auth = request.authorization 
     if not auth or not check_auth(auth.username, auth.password): 
      abort(401) 
     return f(*args, **kwargs) 
    return decorated 


@app.route('/') 
@requires_auth 
def hello(): 
    return "Hello World" 


if __name__ == "__main__": 
    app.run(debug=True) 

マイリクエストファイル:

import requests, base64 
usrPass = "admin:pass" 
b64Val = base64.b64encode(usrPass) 
from requests.auth import HTTPBasicAuth 
from requests.packages.urllib3.exceptions import InsecureRequestWarning 
requests.packages.urllib3.disable_warnings(InsecureRequestWarning) 
res = requests.get('http://127.0.0.1:5000/', auth=HTTPBasicAuth('admin','pass'), headers={'Authorization': 'Basic %s' % b64Val}, data={}, verify=False) 
print res 

をあなたはlocalhostアドレスを使用する必要があり、ローカルホスト上でこれを実行している場合。
<abc.com>はあなたのコードにあります。これはおそらくエラーです。

EDIT 2

from itsdangerous import TimedJSONWebSignatureSerializer as Serializer, BadSignature, SignatureExpired 


def gen_token(name,passw, expiration=None): 
    s = Serializer(app.config['SECRET_KEY'], expires_in = expiration) 
    return s.dumps(name, passw) 

def verify_token(token): 
    serial = Serializer(app.config['SECRET_KEY']) 
    try: 
     data = serial.loads(token) 
    except BadSignature: 
     return "Error" 
    except SignatureExpired: 
     return "Error" 

    name = data[0] 
    passw = data[1] 

    return name,passw 

これらは、トークンベースの認証を開始するのに役立つだろう方法のカップルです。私は

  1. ユーザー要求があなたがusernamepasswordが正しいことを確認した後、使用してトークンを生成することができます
  2. 認証ヘッダーでユーザー名とパスワードを使用してリクエストを送信することにより、サーバからトークンれた何をしたか

    gen_tokenメソッド。必要に応じてこのメソッドを変更することができます。 Read Here

  3. ここで、ユーザは、方法2から受信したトークンをAuthヘッダーのusernameの場所に送信します。 passwordは空白のままにしてもよいし、Noneをその場所に送ってもよい。
  4. トークンを受け取ったら、SECRET_KEYを使用してトークンをロードする必要があります。あなたの要件に応じて例外を処理することができます。トークンが有効な場合は、リクエストを送信したユーザーを取得して、プロシージャを実行することができます。

希望します。

詳しくは、linkをご覧ください。

+0

私のサーバーに問題があるようです。上記のコードをローカルホスト上で実行しようとしています。しかし、私は私のサーバー、request.authorization同じコードを実行しているときに来ています。 – user1138143

+0

あなたはあなたのスクリプトをどこにデプロイしましたか?あなたのスクリプトは問題ありません。私は、トークンベースの認証を使用してうまく動作するherokuにデプロイされたアプリケーションを持っています。 – formatkaka

+0

トークンベースの認証を開発するのを手伝ってもらえますか?私はちょうどPythonで作業を始めました..まだPythonの認証に精通しています。 – user1138143

0

認証にユーザー名とパスワードを正しく渡していないようです。 usernamepasswordの値は、auth変数から取得する必要があります。これは、フラスコ承認の実施例である

def requires_auth(f): 
    @wraps(f) 
    def decorated(*args, **kwargs): 
     auth = request.authorization 
     if not auth or not check_auth(auth.username, auth.password): 
      return authenticate() 
     return f(*args, **kwargs) 
    return decorated 
+0

ご意見ありがとうございます。私はあなたの提案された変更を試みましたが、それは助けにはなりませんでした。私は問題がauth = request.authorizationであると思う。それはなしとして来る。 – user1138143

関連する問題