zoukankan      html  css  js  c++  java
  • flask-login 整合 pyjwt + json 简易flask框架

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

    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 ,也是简单挺好用的东西

  • 相关阅读:
    Java入门——day28
    第四周进度报告
    Java入门——day27
    Java入门——day26
    Java入门——day25
    Java入门——day24
    Ubuntu创建新用户
    SpringBoot默认的Servlet容器是自带的Tomcat,如何定制和修改配置
    哈希
    找到两张相似的图
  • 原文地址:https://www.cnblogs.com/minsons/p/8047331.html
Copyright © 2011-2022 走看看