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做服务
- config.py
class settings(object): host = 'localhost' port = 12306 secret = b'---------00000???\\'
- mongodb保存数据
user ={ 'name':'user1', 'passwd':'passwd', 'ident':0 #public } admin = { 'name':'bottle', 'passwd':'passwd2', 'ident':1 #admin }
- /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
- 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
- /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的权限认证呢?