• Python Bottle基于 token 的认证应用


    • #JWT

    '''
    JWT 代表 JSON Web Token ,它是一种用于认证头部的 token 格式。这个 token 帮你实现了在两个系统之间以一种安全的方式传递信息。
    我们暂且把 JWT 作为“不记名 token”。一个不记名 token 包含了三部分:header,payload,signature。

    header 是 token 的一部分,用来存放 token 的类型和编码方式,通常是使用 base-64 编码。

    payload 包含了信息。你可以存放任一种信息,比如用户信息,产品信息等。它们都是使用 base-64 编码方式进行存储。
    signature 包括了 header,payload 和密钥的混合体。密钥必须安全地保存储在服务端。

    (https://zhuanlan.zhihu.com/p/19920223)

    '''

    • Python jwt

    https://github.com/jpadilla/pyjwt

    # -*-coding:utf-8 -*-
    
    import jwt
    
    secret = b'???\//>000'
    
    encoded = jwt.encode({'user': 'bottle'}, secret, algorithm='HS256')
    print encoded
    
    decoded = jwt.decode(encoded, secret, algorithms=['HS256'])
    
    print decoded
    
    • 实践

    使用mongodb保存用户数据

    使用bottle做服务

    1. config.py
    class settings(object):
        host = 'localhost'
    
        port = 12306
    
        secret = b'---------00000???\'
    

      

    1. mongodb保存数据
    user ={
        'name':'user1',
        'passwd':'passwd',
        'ident':0 #public
    }
    
    admin = {
        'name':'bottle',
        'passwd':'passwd2',
        'ident':1 #admin
    }
    
    1. /login路由
    @app.route('/login', method='POST')
    def login():
        name   = request.forms.get('name')
        passwd = request.forms.get('passwd')
        ret = db.user.find_one({'name':name})
        if ret and ret['passwd'] == passwd:
             if ret.get('token', None):
                res = {
                    'status': False,
                    'data': "Error occured: " + 'User already logined!'
                 }
                return res
             token = jwt.encode({'user': name, 'ident':ret['ident']}, settings.secret, algorithm='HS256')
             db.user.update({'name':name}, {'$set':{'token':token}})
             res = {
                'status': True,
                'data': name,
                'token': token
             }
             return res
        else:
            res = {
                'type': False,
                'data': "Error occured: " + 'User name or password wrong!!!'
            }
            return res
    
    1. login_required  验证
    def login_required():
        def decorator(func):
            def wrapper(*args, **kwargs):
                authorization = request.headers.get('authorization')
                if not authorization:
                     abort(403, "Sorry, access denied.")
                return func(authorization)
      return wrapper return decorator
    1. /me 测试路由
    @app.route('/me')
    @login_required()
    def me(token):
        ret = db.user.find_one({'token':token})
        if ret:
            ret.pop('_id')
            res = {
                'type':True,
                'data':ret
            }
            return res
        else:
            res = {
                'type':False,
                'data':"Error occured: " + ret
            }
            return res
    
    • 测试

    使用curl测试

    获取token
    curl -d 'name=bottle&passwd=passwd2' http://localhost:8080/login
    
    使用token获取资源
    curl -H 'authorization:your_token' http://localhost:8080/me

      

    • 总结

    测试结果十分满意的。

    不过个人发现了几个问题或者说不足

    1,使用pyjwt每次生成token是一样的?

    2,token是不是还应该有时效?

    3,  现在只是拿到token,那么token的权限认证呢?

  • 相关阅读:
    22.json&pickle&shelve
    22.BASE_DIR,os,sys
    21.time和random
    21.模块的执行以及__name__
    21.python的模块(Module)和包(Package)
    21. 对文件进行查询修改等操作
    20.装饰器和函数闭包
    19.python基础试题(三)
    19.生产者消费者模型
    19.yield和send的区别
  • 原文地址:https://www.cnblogs.com/shiv/p/5748843.html
Copyright © 2020-2023  润新知