码迷,mamicode.com
首页 > Web开发 > 详细

flask_login 整合 pyjwt + json 简易flask框架

时间:2017-12-16 19:45:06      阅读:325      评论:0      收藏:0      [点我收藏+]

标签:手机   adt   ken   应用   就是   secret   第一步   xiaomi   init   

现在很多框架都实现前后端分离,主要为了适应以下几个目的:

1,前后端的分离,可以使前端开发和后端开发更加分工明确,而不是后端还需要在视图模板中加入很多{% XXXX %}标签

2,是为了适应跨域调用或者多客户端调用,如你的手机应用调用某个接口,大都是调用第三方api等

所以在整合JWT,让框架具有更多的适应性。JWT 说简单就是基于token的权限验证;flask 有提供json的支持,可是对象转化是一个大问题;

其实,也不用彻底转化为对象,能满足字典存取值就足够;如果有时间就考虑完善这个整合框架成一个快捷开发框架。

 

第一步:flask 整合 flask_login 

 1) 配置user类

class User(UserMixin,db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    password= db.Column(db.String(128))
    avatar_hash = db.Column(db.String(32))
    session_token=123213dsfw3432

    def __init__(self,id,username,email):
        self.id = id
        self.username = username
        self.email = email

    def get_id(self):
        return self.session_token

    def __repr__(self):
        return <User %r> % self.username

其中的get_id(self)是针对token验证提供,目的是根据token去数据库查询用户,但其实是没用作用的,因为数据库根本就没存这东西,也没有在

@login_manager.user_loader定义下函数使用;
2) 配置 view的回调函数
@login_manager.user_loader
    def load_user(userid):
        user = getUserById(userid)
        return user
        
@login_manager.request_loader
    def load_user_from_request(request):
        api_key = request.headers.get(Authorization)
        print(api_key)
        if api_key:
            obj = jwtDecoding(api_key)
            user = obj[some]
            if user:
                user = getUserById(user[id])
                return user
            else:
                print("is exception !!!!"+str(obj[error_msg]))
                return None
@login_manager.request_loader 是对每次请求时,对应请求头的token做验证的,具体可以去看看官方文档,不再重复。

3)配置启动apps

技术分享图片

具体的内容如下:
from flask import Flask, request,make_response

from flask_login import LoginManager

login_manager = LoginManager()


def create_app(config=None):
    app = Flask(__name__)
    #app.config.from_object(config)
    if config is not None:
        app.config.from_pyfile(config)
    # send CORS headers
    @app.after_request
    def after_request(response):
        response.headers.add(Access-Control-Allow-Origin, *)
        if request.method == OPTIONS:
            response.headers[Access-Control-Allow-Methods] = DELETE, GET, POST, PUT
            headers = request.headers.get(Access-Control-Request-Headers)
            if headers:
                response.headers[Access-Control-Allow-Headers] = headers
                ##response.headers[Authorization] = xiaominggessdfs3432ds34ds32432cedsad332e23
        return response

    from apps.model1 import db
    db.init_app(app)

    login_manager.session_protection = "strong"
    login_manager.init_app(app)

    from apps.test1.view import init_api
    init_api(app)

    return app

 到这里说明 flask_login 整合ok了

第二步,整合pyjwt

1)首先定义一个jwt使用的工具类:

import jwt
import datetime
import hashlib

SECRECT_KEY = secret

def md5Encoding(youstr):
    m=hashlib.md5()
    m.update(youstr)
    encodingstr=m.hexdigest()
    print(encodingstr)


# 生成jwt 信息
def  jwtEncoding(some,aud=webkit):
    datetimeInt = datetime.datetime.utcnow() + datetime.timedelta(seconds=180)
    print(datetimeInt)
    option = {
        exp:datetimeInt,
        aud: aud,
        some: some
    }
    encoded2 = jwt.encode(option, SECRECT_KEY, algorithm=HS256)
    return encoded2


# userInfo = {
#             "id":12,
#             "username":"2234",
#             "email":"23423dsd"
#         }
#
# listr = jwtEncoding(userInfo)
# print(listr.decode())


# 解析jwt 信息
def  jwtDecoding(token,aud=webkit):
    decoded = None
    try:
        decoded = jwt.decode(token, SECRECT_KEY, audience=aud, algorithms=[HS256])
    except jwt.ExpiredSignatureError :
        print("erroing.................")
        decoded = {"error_msg":"is timeout !!","some":None}
    except Exception:
        decoded ={"error_msg":"noknow exception!!","some":None}
        print("erroing2.................")
    return decoded

 2)整合pycharm到flask_login

 其实上面红色的代码就是说明已经整合到flask_login里面去了,你是不是觉得很简单,当然还得提供一个登陆的功能,生成token:

@app.route(/login, methods=[GET, POST])
    def login():
        str = request.get_json()
        print(str)
        name = str[username]

        admin = User.query.filter_by(username=name).first() #这里需要重新修改成成缓存里取,减少处理时间

        userInfo = {
            "id":admin.id,
            "username":admin.username,
            "email":admin.email
        }

        if admin == None:
            return jsonify(trueReturn("{‘ok‘:Flase}", "not the user"))
        else:
            #request.headers[Authorization]=liuliuyyeshibushidslfdslfsdkfkdsf23234243kds
            #login_user(admin)
            token = jwtEncoding(userInfo)
            print(token)
            return jsonify(trueReturn("{‘ok‘:True,‘token‘:"+token.decode()+"}", "you are sucess"))

如果验证出错就会在 obj = jwtDecoding(api_key) 里面报错,所以在这里,你需要捕捉错误,并提示出来,工具类只是简单捕捉,这一块还需要完善一点。

3)例子演示

1,登陆:

技术分享图片

可以看到成功,并返回token了

2,操作一些有权限要求的接口:

 @app.route(/cun)
    @login_required  #登陆验证要求
    def getUser2():
        user=utils._get_user() ##通过flask_login manage 中获取用户
        print(user.__dict__)
        return jsonify(trueReturn("{‘ok‘:True}", "cun success!!!!!"))

技术分享图片

 

请求前,必须加消息头Authorization ,里面的内容为token字符串,也可以自定义规范格式

3,过期效果:

 jwt里面加了时间期限

技术分享图片

技术分享图片

有一个缺陷就是缺少日期的token 日期的刷新功能,登陆后一段时间就过期了,应该加个每次请求一段时间就刷新token的功能,

这些对于你们来说,就是小事改改就行。

源码给你们提供出来:https://files.cnblogs.com/files/minsons/teston2.zip (下载

参考:

pyJWT:https://pyjwt.readthedocs.io/en/latest/usage.html

flask_login:https://flask-login.readthedocs.io/en/latest/#flask_login.confirm_login

flask_jwt :http://pythonhosted.org/Flask-JWT/ 这个源两年多没更新了,里面其实也是调用pyjwt,建议不要用了

flask-httpauth :http://flask-httpauth.readthedocs.io/en/latest/ 也可以考虑用flask-httpauth 整合pyjwt ,也是简单挺好用的东西

 

flask_login 整合 pyjwt + json 简易flask框架

标签:手机   adt   ken   应用   就是   secret   第一步   xiaomi   init   

原文地址:http://www.cnblogs.com/minsons/p/8047331.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!