在线不卡日本ⅴ一区v二区_精品一区二区中文字幕_天堂v在线视频_亚洲五月天婷婷中文网站

  • <menu id="lky3g"></menu>
  • <style id="lky3g"></style>
    <pre id="lky3g"><tt id="lky3g"></tt></pre>

    Flask博客實戰(zhàn) – 實現(xiàn)登錄注冊功能

    Flask博客實戰(zhàn) - 實現(xiàn)登錄注冊功能

    上一節(jié)我們已經(jīng)創(chuàng)建了一個用戶應(yīng)用,并創(chuàng)建了用戶模型,那么我們這節(jié)就開始實現(xiàn)一個簡單的用戶登錄注冊功能!

    登錄注冊功能Flask有一個非常優(yōu)秀的擴(kuò)展Flask-login,我們可以選擇使用這個擴(kuò)展來實現(xiàn),但為了學(xué)習(xí)我們暫時不使用這個第三方擴(kuò)展,而是選擇使用session來實現(xiàn)!

    實現(xiàn)用戶的登錄功能

    首先,我們需要完善登錄的html頁面, 路徑為:app/auth/templates/login.html

    {% extends ‘base.html’ %}{% block title %} 登錄頁 {% endblock title %}{% block hero %}{% endblock hero %}{% block main %} {% block auth_form %} {% endblock auth_form %} {% endblock main %}

    代碼詳解:

    這個登陸模板繼承了base.html的樣式,這個base.html中的模塊及代碼其實就是我們之前實現(xiàn)的首頁,只是我們把他作為一個模板基類來繼承他!

    這段代碼中其實就是寫了一個輸入賬號密碼表單,其他多余的代碼都是為了實現(xiàn)表單的樣式而存在的!

    這里要特別說明的是這個input表單必須設(shè)置name屬性,因為后端要根據(jù)此name屬性來獲取用戶輸入的值!其他屬性則需要大家自行去了解學(xué)習(xí)!

    登錄功能的后端邏輯視圖, 路徑為:app/auth/views/auth.py

    @bp.route(‘/login’, methods=[‘GET’, ‘POST’])def login(): # 登錄視圖 if request.method == ‘POST’: username = request.form[‘username’] password = request.form[‘password’] error = None user = auth.User.query.filter_by(username=username).first() if user is None: error = ‘該用戶不存在!’ elif not check_password_hash(user.password, password): error = ‘密碼不正確.’ if error is None: session.clear() session[‘user_id’] = user.id return redirect(url_for(‘index’)) flash(error) return render_template(‘login.html’)

    代碼詳解: – request.method == ‘POST’判斷當(dāng)前請求是否為post請求方式 – error = None 來初始化一個錯誤變量,如果未通過登錄驗證,把錯誤信息通過消息傳送到頁面提示用戶

    user = auth.User.query.filter_by(username=username).first()if user is None: error = ‘該用戶不存在!’elif not check_password_hash(user.password, password): error = ‘密碼不正確.’

    這段代碼首先在數(shù)據(jù)庫通過用戶提交的用戶名去查詢該用戶,用戶不存在就會返回None返回錯誤提示,用戶存在則判斷密碼是否正確,這里用到了一個check_password_hash()的方法,這是用來將密文密碼解密后與用戶輸入密碼比對方法,與之對應(yīng)的有一個generate_password_hash()的方法用來加密明文密碼保存到數(shù)據(jù)庫!

    if error is None: session.clear() session[‘user_id’] = user.id return redirect(url_for(‘index’))flash(error)

    這段代碼則是如果沒有返回任何錯誤提示,說明該提交的表單符合我們的要求,并且數(shù)據(jù)庫也存在該用戶信息,那么我們只需要清空session,重新將session中的user_id設(shè)置為當(dāng)前登錄的id即可!

    因此在實現(xiàn)登錄注冊邏輯之前就必須引入這兩個方法:

    from werkzeug.security import check_password_hash, generate_password_hash

    登錄功能雖然實現(xiàn)了,但我們數(shù)據(jù)庫目前還沒有任何一個用戶,所以此時就應(yīng)該要去實現(xiàn)用戶的注冊功能,向數(shù)據(jù)庫新增用戶,大概的邏輯是,用戶輸入用戶名及兩次密碼,先判斷該用戶是否已經(jīng)存在,存在則提示更換用戶名,不存在則向數(shù)據(jù)庫創(chuàng)建該用戶信息,并清空session,重新設(shè)置user_id的值為注冊用戶的id,以達(dá)到注冊成功后自動登錄的目的!

    實現(xiàn)用戶的注冊功能

    首先,我們需要完善注冊的html頁面, 路徑為:app/auth/templates/register.html

    {% extends ‘login.html’ %}{% block title %}注冊{% endblock title %}{% block auth_form %}{% endblock auth_form %}

    這是注冊頁面的html,大家自行理解下,這里著重說一個我們在視圖中通過flash()傳遞出來的消息,在模板中由以下代碼接收!

    {% with messages = get_flashed_messages() %} {% if messages %}

      {% for message in messages %}

    • {{ message }}
    • {% endfor %}

    {% endif %} {% endwith %}

    注冊功能的后端邏輯視圖, 路徑為:app/auth/views/auth.py

    @bp.route(‘/register’, methods=[‘GET’, ‘POST’])def register(): # 注冊視圖 if request.method == ‘POST’: username = request.form[‘username’] password = request.form[‘password’] password1 = request.form[‘password1’] if password != password1: flash(‘兩次密碼輸入不一致!’) return redirect(url_for(‘auth.register’)) exists_user = auth.User.query.filter_by(username=username).first() if exists_user: flash(‘該用戶名已經(jīng)存在,請更換其他用戶名!’) return redirect(url_for(‘auth.register’)) else: user = auth.User(username=username, password=generate_password_hash(password)) db.session.add(user) db.session.commit() session.clear() session[‘user_id’] = user.id return redirect(url_for(‘index’)) return render_template(‘register.html’)

    這個注冊的邏輯基本上涵蓋了我們之前所有章節(jié)學(xué)到的知識點,這里就不再過多地去一一解釋代碼,大家可自行理解并完善注釋!

    實現(xiàn)用戶退出登錄功能

    通過登錄和注冊功能的實現(xiàn),我們已經(jīng)清楚地知道,用戶是否登錄其實是判斷session會話中是否存在用戶的id來決定,那么推出登錄,我們只需要清除session會話中的用戶id即可,這里我們直接選擇清空session的方式實現(xiàn)推出功能!

    @bp.route(‘/logout’)def logout(): # 注銷 session.clear() return redirect(url_for(‘index’))

    在模板中獲取用戶信息

    @bp.before_app_requestdef load_logged_in_user(): # 每個請求之前都回去session中查看user_id來獲取用戶 user_id = session.get(‘user_id’) if user_id is None: g.user = None else: g.user = auth.User.query.get(int(user_id))

    bp.before_app_request()注冊一個在視圖函數(shù)之前運(yùn)行的函數(shù),無論請求什么 URL。 都會先檢查用戶 ID 是否存儲在會話中,并從數(shù)據(jù)庫獲取該用戶的數(shù)據(jù),將其存儲在 g.user 上,該數(shù)據(jù)在請求期間持續(xù)。

    注冊完這個函數(shù)之后,我們就可以在base.html中的導(dǎo)航的最右側(cè)通過g.user的返回值,判斷用戶是否已經(jīng)登錄,顯示不同的信息!

    {% block navbar %} Home … 省略部分代碼 {% if g.user %} 歡迎您 {{ g.user[‘username’] }} 個人中心 退出 {% else %} Sign up Log in {% endif %} {% endblock navbar %}

    實現(xiàn)login_required裝飾器

    對于像下一章節(jié)我們要實現(xiàn)的用戶中心以及管理后臺,則必須是帶有權(quán)限的訪問,最基本的權(quán)限應(yīng)該是必須是登錄用戶,那么所以說對于那些未登錄的用戶我們需要拒絕訪問的功能!

    這個其實思路也非常簡單,既然在實現(xiàn)模板中調(diào)用用戶信息的時候,我們把當(dāng)前登錄的用戶信息添加到了g對象,那么我們只需要判斷g.user的返回值是否為None即可判斷用戶是否登陸!

    def login_required(view): # 限制必須登錄才能訪問的頁面裝飾器 @functools.wraps(view) def wrapped_view(**kwargs): if g.user is None: return redirect(url_for(‘auth.login’)) return view(**kwargs) return wrapped_view

    到這里關(guān)于用戶登錄注冊相關(guān)的基本權(quán)限問題我們就完成了,注意這些視圖函數(shù)都在app/auth/views/auth.py文件中!

    鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
    上一篇 2022年6月21日 06:45
    下一篇 2022年6月21日 06:45

    相關(guān)推薦

    聯(lián)系我們

    聯(lián)系郵箱:admin#wlmqw.com
    工作時間:周一至周五,10:30-18:30,節(jié)假日休息