Flask
中通常使用Flask-login
进行登录验证,而Flask-login
使用的是Session
实现的登录状态验证,这样就导致每次重新打开网页的时候需要重复登录,或者当出现分布式的时候由于其他服务器可能未与客户端建立连接无法获取登录状态。这时候我们就可以通过Token
令牌实现服务端与客户端登录状态验证。

通过上图可以简单整理下token验证的流程:
1、用户登录请求服务器;
2、服务器验证登录信息,根据用户信息生成一个token,并将token和用户信息包装返回给客户端;
3、客户端将返回的token保存在本地,在每次api请求的时候将token写入到请求头部;
4、服务端处理API请求时,获取头部token信息,验证token的合法性,并通过token获取用户信息,处理api,返回api信息给客户端。
flask-httpauth安装
Flask中使用flask-httpauth可以实现token的验证,安装如下:
$ pip install flask-httpauth
使用示例
如下通过一个验证示例来了解如何使用flask-httpauth
,flask-httpauth插件支持用户验证方式有:HTTPAuth
、HTTPBasicAuth
、HTTPDigestAuth
、HTTPTokenAuth
、MultiAuth
几种验证方式。本文主要是介绍HTTPTokenAuth
方式实现验证,示例代码如下:
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
一样,如果令牌有效,该函数应返回用户对象。
JWS实现示例
Flask-HTTPAUTH仓库提供了一个JWS实现的完整示例。WS 令牌类似于 JWT 令牌。但是,使用 JWT 令牌需要外部依赖。如下给出认证示例:
from flask import Flask
from flask_httpauth import HTTPTokenAuth
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
app = Flask(__name__)
app.config['SECRET_KEY'] = 'top secret!'
token_serializer = Serializer(app.config['SECRET_KEY'], expires_in=3600)
auth = HTTPTokenAuth('Bearer')
users = ['john', 'susan']
for user in users:
token = token_serializer.dumps({'username': user}).decode('utf-8')
print('*** token for {}: {}\n'.format(user, token))
@auth.verify_token
def verify_token(token):
try:
data = token_serializer.loads(token)
except: # noqa: E722
return False
if 'username' in data:
return data['username']
@app.route('/')
@auth.login_required
def index():
return "Hello, %s!" % auth.current_user()
if __name__ == '__main__':
app.run()
可以通过curl
命令验证结果如下:
curl -X GET -H "Authorization: Bearer <jws-token>" http://localhost:5000/