胖蔡说技术
随便扯扯

Flask-HTTPAuth实现flask应用的登录验证

Flask-Httpauth是一个Flask扩展,可简化使用Flask路由的HTTP身份验证。Flask-HTTPAuth提供了多个验证方式实现验证。验证方式如下:

  • HTTPBasicAuth:http基础身份验证保护路由
  • HTTPDigestAuth:http摘要认证
  • HTTPTokenAuth:使用Token实现路由和api的认证
  • MultiAuth:多种验证方式组合

HTTPBasicAuth

Flask-HTTPAuth扩展插件提供HTTPBasicAuth类实现http的基本验证实现,其实现原理图如下:

Flask-HTTPAuth提供实现的基础认证示例如下:

from flask import Flask
from flask_httpauth import HTTPBasicAuth
from werkzeug.security import generate_password_hash, check_password_hash

app = Flask(__name__)
auth = HTTPBasicAuth()

users = {
    "john": generate_password_hash("hello"),
    "susan": generate_password_hash("bye")
}

@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, {}!".format(auth.current_user())

if __name__ == '__main__':
    app.run()

verify_password 装饰器装饰的函数接收客户端发送的用户名和密码。如果凭据属于用户,则该函数应返回用户对象。如果凭据无效,该函数可以返回 None False。然后可以从身份验证实例的 current_user() 方法查询用户对象。

HTTPDigestAuth

Flask-HTTPAuth提供HTTPDigestAuth实现HTTP的摘要认证。其实现通过请求头WWW-Authenticate辅助验证,其原理图如下:

其使用示例代码如下:

from flask import Flask
from flask_httpauth import HTTPDigestAuth

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret key here'
auth = HTTPDigestAuth()

users = {
    "john": "hello",
    "susan": "bye"
}

@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, {}!".format(auth.username())

if __name__ == '__main__':
    app.run()

HTTPTokenAuth

Flask-HTTPAuth通过HTTPTokenAuth实现API和路由的登录认证。其实现原理是通过token实现身份的认证。其实现原理如下:

其实现代码示例如下:

from flask import Flask
from flask_httpauth import HTTPTokenAuth

app = Flask(__name__)
auth = HTTPTokenAuth(scheme='Bearer')

tokens = {
    "secret-token-1": "john",
    "secret-token-2": "susan"
}

@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())

if __name__ == '__main__':
    app.run()

HTTPTokenAuth 是一个通用的身份验证处理程序,可以与非标准身份验证方案一起使用,方案名称作为构造函数中的参数给出。在上面的示例中,服务器提供的 WWW-Authenticate 标头将使用 Bearer 作为方案:

WWW-Authenticate: Bearer realm="Authentication Required"

verify_token 回调接收客户端在 Authorization 标头上提供的身份验证凭据。这可以是一个简单的标记,也可以包含多个参数,函数必须从字符串中解析和提取这些参数。与 verify_password 一样,如果令牌有效,该函数应返回用户对象。

MultiAuth

应用有时需要支持身份验证方法的组合。例如,可以通过通过基本身份验证发送客户端ID和秘密来验证Web应用程序,而第三方API客户端使用JWSJWT BEARER令牌。 Multiauth类允许您保护具有多个身份验证对象的路由。要授予对端点的访问,必须验证其中一种身份验证方法。

用户角色

Flask-HTTPAuth 包括一个简单的基于角色的身份验证系统,可以选择添加该系统以在过滤对路由的访问时提供额外的粒度层。要启用角色支持,请编写一个函数来返回给定用户的角色列表,并使用 get_user_roles 装饰器对其进行装饰:

@auth.get_user_roles
def get_user_roles(user):
    return user.get_roles()

要限制具有给定角色的用户访问路由,请将角色参数添加到 login_required 装饰器:

@app.route('/admin')
@auth.login_required(role='admin')
def admins_only():
    return "Hello {}, you are an admin!".format(auth.current_user())

role 参数可以采用角色列表,在这种情况下,具有任何给定角色的用户将被授予访问权限:

@app.route('/admin')
@auth.login_required(role=['admin', 'moderator'])
def admins_only():
    return "Hello {}, you are an admin or a moderator!".format(auth.current_user())

在最高级的用法中,可以通过多个角色来过滤用户:

@app.route('/admin')
@auth.login_required(role=['user', ['moderator', 'contributor']])
def admins_only():
    return "Hello {}, you are a user or a moderator/contributor!".format(auth.current_user())

部署

请注意,某些Web服务器默认情况下不会将授权标题传递到WSGI应用程序。例如,如果您将ApacheMOD_WSGI一起使用,则必须在此处记录的“ wsgipassauthorization”设置选项。

弃用的基本身份验证选项

在上述 verify_password 存在之前,还有其他更简单的机制来实现基本身份验证。虽然这些已被弃用,但它们仍然得到维护。但是,应该首选 verify_password 回调,因为它提供了更高的安全性和灵活性。

get_password回调需要返回与给出的用户名关联的密码。 flask-httpauth仅在get_password(用户名)==密码时才允许访问。例子:

@auth.get_password
def get_password(username):
    return get_password_for_username(username)

通常,仅使用此回调并不是一个好主意,因为它需要密码以服务器中的明文提供。在更有可能将密码存储在用户数据库中的情况下,则需要附加回调来定义如何哈希密码:

@auth.hash_password
def hash_pw(password):
    return hash_password(password)


在此示例中,您必须将hash_password()替换为应用程序中使用的特定哈希功能。当提供hash_password回调后,当get_password(username)== hash_password(password)时,将授予访问权限。

如果哈希算法需要已知用户名,则回调可以进行两个参数,而不是一个参数:

@auth.hash_password
def hash_pw(username, password):
    salt = get_salt(username)
    return hash_password(password, salt)
赞(0) 打赏
转载请附上原文出处链接:胖蔡说技术 » Flask-HTTPAuth实现flask应用的登录验证
分享到: 更多 (0)

请小编喝杯咖啡~

支付宝扫一扫打赏

微信扫一扫打赏