zoukankan      html  css  js  c++  java
  • 基于Flask的 api(四)

    restful安全认证

    Flask-HTTPAuth是一个简单的扩展,它简化了使用Flask路由的HTTP身份验证的使用

     安装 Flask-HTTPAuth

    pip install Flask-HTTPAuth

    认证方式有 Basic 、Digest、token

    1.Basic认证

    使用HTTP基本身份验证来保护路由

    from flask import Flask,jsonify
    from flask_httpauth import HTTPBasicAuth
    from werkzeug.security import generate_password_hash, check_password_hash
    
    app = Flask(__name__)
    auth = HTTPBasicAuth()
    users = {
        "aaa": generate_password_hash("123"),
        "bbb": generate_password_hash("456")
    }
    
    @auth.verify_password
    def verify_password(username, password):
        if username in users and 
                check_password_hash(users.get(username), password):
            return username
    
    @app.route('/')
    @auth.login_required
    def index():
        return "Hello, %s!" % auth.current_user()
    
    if __name__ == "__main__":
        app.run(debug=True)

    测试

    $ curl  -i http://localhost:5000
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100    19  100    19    0     0     81      0 --:--:-- --:--:-- --:--:--    81HTTP/1.0 401 UNAUTHORIZED
    Content-Type: text/html; charset=utf-8
    Content-Length: 19
    WWW-Authenticate: Basic realm="Authentication Required"
    Server: Werkzeug/1.0.1 Python/3.6.0
    Date: Mon, 23 Nov 2020 15:24:26 GMT
    
    Unauthorized Access

    使用curl时添加 -u (或 - user )

    $ curl -u aaa:123 -i http://localhost:5000
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100    11  100    11    0     0     15      0 --:--:-- --:--:-- --:--:--    15HTTP/1.0 200 OK
    Content-Type: text/html; charset=utf-8
    Content-Length: 11
    Server: Werkzeug/1.0.1 Python/3.6.0
    Date: Mon, 23 Nov 2020 15:24:44 GMT
    
    Hello, aaa!

    将验证添加到获取资源上

    from flask import Flask,jsonify
    from flask_httpauth import HTTPBasicAuth
    from werkzeug.security import generate_password_hash, check_password_hash
    
    app = Flask(__name__)
    auth = HTTPBasicAuth()
    users = {
        "aaa": generate_password_hash("123"),
        "bbb": generate_password_hash("456")
    }
    
    @auth.verify_password
    def verify_password(username, password):
        if username in users and 
                check_password_hash(users.get(username), password):
            return username
    
    @app.route('/')
    @auth.login_required
    def index():
        return "Hello, %s!" % auth.current_user()
    
    tasks = [
        {
            'id': 1,
            'title': u'Buy groceries',
            'description': u'Milk, Cheese, Pizza, Fruit, Tylenol',
            'done': False
        },
        {
            'id': 2,
            'title': u'Learn Python',
            'description': u'Need to find a good Python tutorial on the web',
            'done': False
        }
    ]
    
    @app.route("/tasks", methods=['GET'])
    @auth.login_required
    def get_tasks():
        return jsonify({'tasks': tasks})
    
    if __name__ == "__main__":
        app.run(debug=True)

    测试

    $ curl -i http://localhost:5000/tasks
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100    19  100    19    0     0     80      0 --:--:-- --:--:-- --:--:--    80HTTP/1.0 401 UNAUTHORIZED
    Content-Type: text/html; charset=utf-8
    Content-Length: 19
    WWW-Authenticate: Basic realm="Authentication Required"
    Server: Werkzeug/1.0.1 Python/3.6.0
    Date: Mon, 23 Nov 2020 15:33:14 GMT
    
    Unauthorized Access
    
    Bei@DESKTOP-LCBJFJ2 MINGW64 /d/Python/dxfWrite
    $ curl -u aaa:123 -i http://localhost:5000/tasks
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100   317  100   317    0     0    751      0 --:--:-- --:--:-- --:--:--   751HTTP/1.0 200 OK
    Content-Type: application/json
    Content-Length: 317
    Server: Werkzeug/1.0.1 Python/3.6.0
    Date: Mon, 23 Nov 2020 15:33:19 GMT
    
    {
      "tasks": [
        {
          "description": "Milk, Cheese, Pizza, Fruit, Tylenol",
          "done": false,
          "id": 1,
          "title": "Buy groceries"
        },
        {
          "description": "Need to find a good Python tutorial on the web",
          "done": false,
          "id": 2,
          "title": "Learn Python"
        }
      ]
    }

    2.Digest

    使用HTTP摘要式身份验证

    from flask import Flask,jsonify
    from flask_httpauth import HTTPDigestAuth
    
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'key123456'
    auth = HTTPDigestAuth()
    users = {
        "aaa": "123",
        "bbb": "456"
    }
    
    @auth.get_password
    def get_pw(username):
        if username in users:
            return users.get(username)
        return None
    
    @app.route('/')
    @auth.login_required
    def index():
        return "Hello, %s!" % auth.username()
    
    tasks = [
        {
            'id': 1,
            'title': u'Buy groceries',
            'description': u'Milk, Cheese, Pizza, Fruit, Tylenol',
            'done': False
        },
        {
            'id': 2,
            'title': u'Learn Python',
            'description': u'Need to find a good Python tutorial on the web',
            'done': False
        }
    ]
    
    @app.route("/tasks", methods=['GET'])
    @auth.login_required
    def get_tasks():
        return jsonify({'tasks': tasks})
    
    if __name__ == "__main__":
        app.run(debug=True)

    测试

    说明:

      a.客户端访问一个受http摘要认证保护的资源

      b.服务器返回401状态以及nonce等信息,要求客户端进行认证

      c.客户端将以用户名,密码,nonce值,HTTP方法, 和被请求的URI为校验值基础而加密(默认为MD5算法)的摘要信息返回给服务器

      d.如果认证成功,则返回相应的资源。如果认证失败,则仍返回401状态,要求重新进行认证

     3.token

    from flask import Flask, g,jsonify
    from flask_httpauth import HTTPTokenAuth
    
    app = Flask(__name__)
    auth = HTTPTokenAuth(scheme='Bearer')
    
    tokens = {
        "token1": "aaa",
        "token2": "bbb"
    }
    
    @auth.verify_token
    def verify_token(token):
        if token in tokens:
            return tokens[token]
    
    @app.route('/')
    @auth.login_required
    def index():
        return "Hello, {}!".format(auth.current_user())
    
    tasks = [
        {
            'id': 1,
            'title': u'Buy groceries',
            'description': u'Milk, Cheese, Pizza, Fruit, Tylenol',
            'done': False
        },
        {
            'id': 2,
            'title': u'Learn Python',
            'description': u'Need to find a good Python tutorial on the web',
            'done': False
        }
    ]
    
    @app.route("/tasks", methods=['GET'])
    @auth.login_required
    def get_tasks():
        return jsonify({'tasks': tasks})
    
    if __name__ == '__main__':
        app.run(debug=True)

    测试

  • 相关阅读:
    codeforces C. No to Palindromes!
    codeforces D. Pashmak and Parmida's problem
    codeforces C. Little Pony and Expected Maximum
    codeforces D. Count Good Substrings
    codeforces C. Jzzhu and Chocolate
    codeforces C. DZY Loves Sequences
    codeforces D. Multiplication Table
    codeforces C. Painting Fence
    hdu 5067 Harry And Dig Machine
    POJ 1159 Palindrome
  • 原文地址:https://www.cnblogs.com/baby123/p/14029757.html
Copyright © 2011-2022 走看看