简单的介绍下flask前后端分离的流程,以及部分底层代码。还有装饰器的内容。
流程
前后端分离的大概流程就是这样。
当用户想要登陆时,访问 /api/login
1 2 3 4 5 6 7 8 9 10 11
| @app.route('/api/login', methods=['POST']) @auth.login_required def get_auth_token(): token = g.user.generate_auth_token() token = str(token, encoding='utf8') print(token) data = { 'token': token, 'username': g.user.username } return jsonify(data)
|
首先,函数会先使用 @auth.login_required 这个装饰器(关于装饰器的介绍请看下文),跟进 flask_httpauth.py 看到如下代码
1 2 3 4 5 6 7 8 9 10 11 12 13
| def login_required(self, f): @wraps(f) def decorated(*args, **kwargs): auth = self.get_auth() if request.method != 'OPTIONS': password = self.get_auth_password(auth)
if not self.authenticate(auth, password): request.data return self.auth_error_callback() return f(*args, **kwargs) return decorated
|
主要看一下装饰器内部,先调用了 self.get_auth() 这个函数的作用就是取到 HTTP 头中用于认证的信息。然后进行判断,如果不是 OPTIONS 包的话,就调用 self.get_auth_password 获取到 HTTP 头中标准验证的密码。然后调用 self.authenticate() 来验证密码的准确性。
跟进 self.authenticate() 函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| def authenticate(self, auth, stored_password): if auth: username = auth.username client_password = auth.password else: username = "" client_password = "" if self.verify_password_callback: return self.verify_password_callback(username, client_password) if not auth: return False if self.hash_password_callback: try: client_password = self.hash_password_callback(client_password) except TypeError: client_password = self.hash_password_callback(username, client_password) return client_password is not None and client_password == stored_password
|
首先函数会对传进的 auth 进行是否为空的判断。然后判断 self.verify_password_callback 是否为空。这个函数就是你自己定义的密码验证的函数。如下。
1 2 3 4
| @auth.verify_password def verify_password(username_or_token, password): '''你的验证函数''' return True
|
跟进下装饰器。
1 2 3
| def verify_password(self, f): self.verify_password_callback = f return f
|
发现这个装饰器就是为 self.verify_password_callback 进行赋值。上面的全部内容就是关于 @auth.login_required 的整个流程。
装饰器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| def log(text): print('text is {}'.format(text))
def deractor(func): print('deractor is running()') def wrapper(*args, **kwargs): return func(*args, **kwargs) return wrapper return deractor @log('WARN') def foo(): print('foo is running')
|
这是因为装饰器的本质就是:foo = log(‘WARN’)(foo) 。对于多个装饰器,如下面代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| def a(f): print(1) def b(f): print(2) def c(f): print(3) @a @b @c def d(): pass
|
某些用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class C(): get_password_callback = None def get_password(self, f): self.get_password_callback = f return f
def prints(self): if self.get_password_callback: self.get_password_callback() else: print(None) c = C() c.prints() @c.get_password def b(): print(1) c.prints()
|