本文最后更新于:2022-02-12T16:25:06+08:00
下面主要完成的是通过Flask实现密码登录,用户成功登录之后,后端返回一个token。此后用户通过token即可访问其他需要验证的网站。
Flask实现密码登录
首先安装所需的模块:
1 2 pip install flask_httpauth pip install itsdangerous
之后创建一个工具对象utils/MyToken.py
,用于生成token以及验证token(通过捕获不同的错误来确定token的状态:正确、错误、过期等):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 from itsdangerous import TimedJSONWebSignatureSerializer as Serializerfrom itsdangerous import BadSignature, SignatureExpired SECRET_KEY = 'xxxxxxx' class Token : @staticmethod def generate_auth_token (user_id, expiration=3600 ): s = Serializer(SECRET_KEY, expires_in=expiration) return s.dumps({'user_id' : user_id}).decode() @staticmethod def verify_auth_token (token ): s = Serializer(SECRET_KEY) try : data = s.loads(token) return data except SignatureExpired: print ("token已经过期" ) return None except BadSignature: print ("token错误" ) return None
之后在Flask前端进行相应的验证配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from flask import Flask, jsonify, g, request, abort, make_response, send_from_directoryfrom flask_cors import CORSfrom flask_httpauth import HTTPBasicAuthfrom utils.MyToken import Token auth_user = HTTPBasicAuth() @auth_user.verify_password def verify_password (username, password ): label, auth = db.hasUser(username, password) if not label: return False g.user_id = username g.user_auth = auth return True
用户名和密码验证主要是使用HTTPBasicAuth,在postman的测试中,指定路径为Authorization -> Basic Auth
。通过verify_password函数来指定验证方式。其中hasUser函数是自己写的函数,可以通过连接数据库,并通过给定的username和password来判定用户id和密码是否匹配,如果匹配,则返回True,否则返回False。
然后在需要用户密码验证的链接之前增加修饰:@auth_user.login_required
如下,完成登录链接的逻辑:
1 2 3 4 5 6 7 @app.route('/login' , methods=['POST' ] ) @auth_user.login_required def login (): user = g.user_id token = Token.generate_auth_token(g.user_id) return jsonify({'token' : token})
如果用户访问该链接,会首先进行auth_use的验证,只有当验证返回True的时候才会进入login函数。login函数中返回token给前端。
Flask实现token验证
token验证的实现与前面类似,同样是通过实现验证函数来完成。token验证主要是使用HTTPTokenAuth,在postman的测试中,指定路径为Authorization -> Bearer Token
。
1 2 3 4 5 6 7 8 9 10 from flask_httpauth import HTTPTokenAuth auth_token = HTTPTokenAuth() @auth_token.verify_token def verify_token (token ): token = re.sub(r'^"|"$' , '' , token) label = Token.verify_auth_token(token) return label
然后在需要token验证的链接之前增加修饰:@auth_token.login_required
1 2 3 4 5 6 @app.route('/data' , methods=['GET' ] ) @auth_token.login_required def allData (): data = db.getData() return data
与前端axios的对接
前端axios完成用户密码的传递(通过auth
指定),这里的密码使用md5加密是为了进行演示,实际情况下一般不会使用md5进行密码的加密:
1 2 3 4 5 6 7 8 9 10 11 let toParams = { username : this .param .username .toString (), password : md5 (this .param .password ).toUpperCase (), }this .$axios({ method : 'POST' , url : this .$store .state .backend_url + 'login' , auth : toParams, })
前端axios完成token的传递(一般是通过axios的拦截器完成):
1 2 3 4 5 6 7 8 9 10 $axios.onRequest (config => { return new Promise ((resolve, reject ) => { let token = app.$cookies .get ('token' ); if (token) config.headers .Authorization = 'Bearer ' + token; resolve (config); }) });
这里涉及到cookies和axios拦截器的使用,内容可以查看相关文章。
参考文章
Flask实现token认证
- -零 - 博客园 (cnblogs.com)