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 ,也是簡單挺好用的東西

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM