如何在Flask中实现登录所需的装饰器

utk*_*sal 9 python flask flask-login

我有两个可以协同工作的Flask应用程序(不同的项目).一个实现了一些使用令牌进行身份验证的API.第二个消耗API并为其创建Web界面.现在我有一个登录函数,它将用户名和密码发送给API,如果正确,则获取auth令牌作为回报.获得令牌后,我将其保存到用户的会话中,现在应该将用户视为登录/验证.如何为这种情况实现login_required装饰器.

这是我的登录功能 -

 def login(self):
        response = make_request(BASE_URL + 'login/', clean_data(self.data))
        if response.status_code == 200:
            session['auth_token'] = response.json().get('auth_token')
            return True
        return False
Run Code Online (Sandbox Code Playgroud)

如何创建login_required装饰器?

如果重要的话,我也使用Redis来存储会话.

小智 17

还可以查看有关装饰器的官方文档:http: //flask.pocoo.org/docs/0.10/patterns/viewdecorators/或python docs https://www.python.org/dev/peps/pep- 0318 /以及.

你的装饰者看起来应该是这样的:

from functools import wraps
from flask import abort
import jwt

def authorize(f):
    @wraps(f)
    def decorated_function(*args, **kws):
            if not 'Authorization' in request.headers:
               abort(401)

            user = None
            data = request.headers['Authorization'].encode('ascii','ignore')
            token = str.replace(str(data), 'Bearer ','')
            try:
                user = jwt.decode(token, JWT_SECRET, algorithms=['HS256'])['sub']
            except:
                abort(401)

            return f(user, *args, **kws)            
    return decorated_function
Run Code Online (Sandbox Code Playgroud)

...然后在你的app.py中你可能有:

@app.route('/api/game', methods=['POST'])
@authorize
def create(user):
    data = json.loads(request.data)
    ....
Run Code Online (Sandbox Code Playgroud)

在这种特殊情况下,我使用JWT作为令牌,你的令牌可以分别不同,令牌的解码可以是你的自定义实现,但基本机制几乎与上面的例子相同.


The*_*ous 2

鉴于每个后续请求都将包含 API 令牌,装饰器应该执行以下操作

  • 接受一般请求。您可以使用 *args 和 **kargs 来实现
  • 从 header 中提取 token 并与 db 中存储的 token 进行比较(不是 Redis,而是生成的 token 存储在后端的任何位置)
  • 如果经过身份验证,则 *args 和 **kargs 应传递给修饰函数
  • 修饰函数的输出应按原样返回
  • 如果身份验证失败,则应返回错误消息。

有关装饰器的说明,请查看此链接: http://thecodeship.com/patterns/guide-to-python-function-decorators/