Table of Contents
为什么需要用token验证
原因呢是因为写博客时已经在本地写好了,但是要发表到网站上还需要这么几步:
- 打开浏览器
- 打开我的网站
- 进入登陆页
- 登陆
- 进入后台页
- 进入文章发表页
- 复制粘贴
- 发表
所以使用token验证成为必然
如何使用token?
生成token
使用itsdangerous对token进行加密
class User(model): ...... @property def token(self): config = current_app.config secret_key = config.setdefault('SECRET_KEY') salt = config.setdefault('SECURITY_PASSWORD_SALT') serializer = URLSafeTimedSerializer(secret_key) # column = self.(需要加密的字段) token = serializer.dumps(column, salt=salt) return token
请保管好SECRET_KEY 和 SECURITY_PASSWORD_SALT,不要泄露
验证token
class User(Model): ...... @staticmethod def check_token(token, max_age=86400): config = current_app.config secret_key = config.setdefault('SECRET_KEY') salt = config.setdefault('SECURITY_PASSWORD_SALT') serializer = URLSafeTimedSerializer(secret_key) try: column = serializer.loads(token, salt=salt, max_age=max_age) except BadSignature: return False except SignatureExpired: return False
- max-age
最大过期时间
如果验证成功查找该用户是否存在
user = User.query.filter_by(column=column).first() if user is None: return False return user
示例:
@staticmethod def check_token(token, max_age=86400): config = current_app.config secret_key = config.setdefault('SECRET_KEY') salt = config.setdefault('SECURITY_PASSWORD_SALT') serializer = URLSafeTimedSerializer(secret_key) try: username = serializer.loads(token, salt=salt, max_age=max_age) except BadSignature: return False except SignatureExpired: return False user = User.query.filter_by(username=username).first() if user is None: return False return user
使用flask-login
flask-login是flask的一个登陆扩展,自带token验证, 但是请一定要设
login_manager.session_protection = "basic"
这是我在试验了n次后,读了flask-login的源码后才发现的(其实后面发现文档有写☹)
然后设置 request_loader
@login_manager.request_loader def user_loader_from_request(request): token = request.args.get('your_token') if token is not None: user = User.check_token(token) if user: return user return login_manager
这是简单的从url中获取token进行验证,也可以从 header中获取(更安全)
token = request.headers.get('your_token')
设置csrf白名单
非常不幸的是,假设你开启了csrf保护,本地使用脚本验证时会报400错误,设置csrf白名单
csrf.exempt
使用脚本发表
直接给出代码
from urllib import request import json content = ''' ,* adssad ,** adasd ,*** adsad ''' data = { 'title': 'hello world', 'content':content } data = json.dumps(data) data = bytes(data, 'utf8') url = 'xxxxx' + '?your_token=' req = request.Request(url, data=data) req.add_header('Content-Type', 'application/json') req.add_header( 'User-Agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.107 Safari/537.36' ) result = request.urlopen(req).read().decode('utf-8') print(result)
现在的步骤是:
- 复制粘贴
- 发表
ok,后续可能还需要将
复制粘贴这一步也去了
本篇文章就是采用这种方式发表