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