flask使用token进行验证


为什么需要用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_KEYSECURITY_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,后续可能还需要将复制粘贴这一步也去了

本篇文章就是采用这种方式发表

作者: honmaple
链接: https://honmaple.me/articles/2016/12/flask使用token进行登陆.html
版权: CC BY-NC-SA 4.0 知识共享署名-非商业性使用-相同方式共享4.0国际许可协议
wechat
alipay

加载评论