Python日記——做一套簡(jiǎn)易的注冊(cè)登錄系統(tǒng)

這次我主要講解如何用python基于Flask的登錄和注冊(cè),驗(yàn)證方式采用Basic Auth
主要用以下庫(kù)

import os
#Flask的基礎(chǔ)庫(kù)
from flask import Flask, abort, request, jsonify, g, url_for
#Flaks的數(shù)據(jù)庫(kù)操作的庫(kù)
from flask.ext.sqlalchemy import SQLAlchemy
#Flask登錄注冊(cè)的庫(kù)
from flask.ext.httpauth import HTTPBasicAuth
#加密解密密碼的庫(kù)
from passlib.apps import custom_app_context as pwd_context
#URL安全序列化工具
from itsdangerous import (TimedJSONWebSignatureSerializer
                          as Serializer, BadSignature, SignatureExpired)

首先當(dāng)然是初始化

app = Flask(__name__)
# 設(shè)置密鑰
app.config['SECRET_KEY'] = 'the quick brown fox jumps over the lazy dog'
# 數(shù)據(jù)庫(kù)的配置
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite'
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True

#數(shù)據(jù)庫(kù)初始化
db = SQLAlchemy(app)
# 驗(yàn)證的初始化
auth = HTTPBasicAuth()

然后是建模

SQLAlchemy是ORM模型操作數(shù)據(jù)庫(kù)的巴碗,所以是非常的方便
除了基本的屬性之后我們我定義了一些必要的方法

class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(32), index=True)
    password_hash = db.Column(db.String(64))
    # 加密密碼
    def hash_password(self, password):
        self.password_hash = pwd_context.encrypt(password)
    # 驗(yàn)證密碼
    def verify_password(self, password):
        return pwd_context.verify(password, self.password_hash)
    # 生成token,并設(shè)置過(guò)期時(shí)間
    def generate_auth_token(self, expiration=600):
        s = Serializer(app.config['SECRET_KEY'], expires_in=expiration)
        return s.dumps({'id': self.id})
    # 靜態(tài)的驗(yàn)證token的方法
    @staticmethod
    def verify_auth_token(token):
        s = Serializer(app.config['SECRET_KEY'])
        try:
            data = s.loads(token)
        except SignatureExpired:
            return None    # token過(guò)期
        except BadSignature:
            return None    # token無(wú)效
        user = User.query.get(data['id'])
        return user

注冊(cè)功能

@app.route('/api/users', methods=['POST'])
def new_user():
    username = request.json.get('username')
    password = request.json.get('password')
    if username is None or password is None:
        abort(400)    # 用戶名或者密碼為空
    if User.query.filter_by(username=username).first() is not None:
        abort(400)    # 用戶已存在
    user = User(username=username)
    # 加密密碼
    user.hash_password(password)
    # 保存進(jìn)數(shù)據(jù)庫(kù)
    db.session.add(user)
    db.session.commit()
    # 成功注冊(cè)后返回用戶名,Location后面接著的是跳轉(zhuǎn)的地址
    return (jsonify({'username': user.username}), 201,
            {'Location': url_for('get_user', id=user.id, _external=True)})

登錄功能

# 登錄后獲取token
@app.route('/api/token')
@auth.login_required
def get_auth_token():
    # 設(shè)置token過(guò)期時(shí)間
    token = g.user.generate_auth_token(600)
    return jsonify({'token': token.decode('ascii'), 'duration': 600})

獲取token后之后愕乎,每次請(qǐng)求只需傳token就好了

我們可以通過(guò)一個(gè)方法驗(yàn)證token是否有效

# 可以通過(guò)token或者賬號(hào)密碼登錄
@app.route('/api/resource')
@auth.login_required
def get_resource():
    # 如果token有效的話就返回username
    return jsonify({'data': 'Hello, %s!' % g.user.username})

細(xì)心的人會(huì)發(fā)現(xiàn)上面這兩個(gè)方法前都帶有@auth.login_required固蚤,這其實(shí)就是奧妙之處

# 有@auth.login_required標(biāo)志的都要調(diào)用這個(gè)方法,傳token或者傳賬號(hào)和密碼
@auth.verify_password
def verify_password(username_or_token, password):
    # 首先驗(yàn)證token
    user = User.verify_auth_token(username_or_token)
    if not user:
        # 然后再驗(yàn)證用戶名和密碼
        user = User.query.filter_by(username=username_or_token).first()
        if not user or not user.verify_password(password):
            return False
    g.user = user
    return True

最后寫(xiě)一個(gè)入口方法

if __name__ == '__main__':
    # 如果這個(gè)數(shù)據(jù)庫(kù)不存在就創(chuàng)建
    if not os.path.exists('db.sqlite'):
        db.create_all()
    app.run(debug=True)

這樣就大功告成了

效果圖

注冊(cè)

注冊(cè)

登錄

獲取token

驗(yàn)證token

驗(yàn)證token
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蔚约,隨后出現(xiàn)的幾起案子吃媒,更是在濱河造成了極大的恐慌,老刑警劉巖爹袁,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件远荠,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡失息,警方通過(guò)查閱死者的電腦和手機(jī)譬淳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)盹兢,“玉大人邻梆,你說(shuō)我怎么就攤上這事∫锩耄” “怎么了浦妄?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)见芹。 經(jīng)常有香客問(wèn)我剂娄,道長(zhǎng),這世上最難降的妖魔是什么辆童? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任宜咒,我火速辦了婚禮,結(jié)果婚禮上把鉴,老公的妹妹穿的比我還像新娘故黑。我一直安慰自己,他們只是感情好庭砍,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布场晶。 她就那樣靜靜地躺著,像睡著了一般怠缸。 火紅的嫁衣襯著肌膚如雪诗轻。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,111評(píng)論 1 285
  • 那天揭北,我揣著相機(jī)與錄音扳炬,去河邊找鬼。 笑死搔体,一個(gè)胖子當(dāng)著我的面吹牛恨樟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播疚俱,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼劝术,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起养晋,我...
    開(kāi)封第一講書(shū)人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤衬吆,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后绳泉,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體逊抡,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年零酪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了秦忿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蛾娶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出潜秋,到底是詐尸還是另有隱情蛔琅,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布峻呛,位于F島的核電站罗售,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏钩述。R本人自食惡果不足惜寨躁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望牙勘。 院中可真熱鬧职恳,春花似錦、人聲如沸方面。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)恭金。三九已至操禀,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間横腿,已是汗流浹背颓屑。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留耿焊,地道東北人揪惦。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像搀别,于是被迫代替她去往敵國(guó)和親丹擎。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 22年12月更新:個(gè)人網(wǎng)站關(guān)停,如果仍舊對(duì)舊教程有興趣參考 Github 的markdown內(nèi)容[https://...
    tangyefei閱讀 35,160評(píng)論 22 257
  • 轉(zhuǎn)載蒂培,覺(jué)得這篇寫(xiě) SQLAlchemy Core再愈,寫(xiě)得非常不錯(cuò)。不過(guò)后續(xù)他沒(méi)寫(xiě)SQLAlchemy ORM... ...
    非夢(mèng)nj閱讀 5,372評(píng)論 1 14
  • 第二部分 Blog例子 第八章 用戶驗(yàn)證 大部分程序需要追蹤用戶身份护戳。當(dāng)用戶連接到程序翎冲,通過(guò)一系列步驟使自己的身份...
    易木成華閱讀 1,281評(píng)論 0 4
  • # Python 資源大全中文版 我想很多程序員應(yīng)該記得 GitHub 上有一個(gè) Awesome - XXX 系列...
    aimaile閱讀 26,441評(píng)論 6 428
  • 或許,你是對(duì)的 你所進(jìn)入和觸到的 都有向上的方向 無(wú)可挑剔的 天空 空空的天空容納光 關(guān)于虛無(wú)和飽滿 一只手輕易舉...
    楊昊田閱讀 294評(píng)論 12 16