Flask-Login/Logout สร้างระบบ Authentication Systems — [ Ep.2] — UserMixin, check_password_hash, flask_wtf, SECRET_KEY

จุดประสงค์

  • เข้าใจและสามารถใช้งาน UserMixin คลาส เพื่อสืบทอดและเรียกใช้งานเมธอดเกี่ยวกับการ Login-Logout ได้
  • เข้าใจและสามารถใช้งาน flask-wtf ได้
  • เข้าใจ flash message
  • เข้าใจ SECRET_KEY และสามารถสร้าง SECRET_KEY เพื่อใช้งานได้
  • ฯลฯ
  • UserMixin
  • login_user
  • logout_user
  • current_user
from flask_login import LoginManager, login_required ,UserMixin, login_user, logout_user, current_user

Flask-WTF

ติดตั้ง flask_wtf

pip install flask_wtf
# form.pyfrom flask_wtf import FlaskFormfrom wtforms import StringField, PasswordField, SubmitFieldfrom wtforms.validators import DataRequired
# form.py...# Login Form Classclass LoginForm(FlaskForm):    username = StringField("Username", validators=[DataRequired()])    password = PasswordField("Password", validators=[DataRequired()])    submit = SubmitField('Submit')
  • username → กำหนดเป็นสตริงฟีลด์ โดยฟีลด์นี้ต้องการ 2 อากิวเมนต์ คือ 1. label กำหนดเป็น “Username” และ 2 คือ validator ที่ใช้ในการ validate ฟอร์ม โดยในที่นี้กำหนดให้มีการ validate
  • password → กำหนดเป็นพาสเวิร์ดฟีลด์ กำหนดเป็นสตริงฟีลด์ โดยฟีลด์นี้ต้องการ 2 อากิวเมนต์ คือ 1. label กำหนดเป็น “Password” และ 2 คือ validator ที่ใช้ในการ validate ฟอร์ม โดยในที่นี้กำหนดให้มีการ validate
  • submit → กำหนดเป็นซับมิตฟีลด์
# form.pyfrom flask_wtf import FlaskFormfrom wtforms import StringField, PasswordField, SubmitFieldfrom wtforms.validators import DataRequired
# Login Form Class
class LoginForm(FlaskForm): username = StringField("Username", validators=[DataRequired()]) password = PasswordField("Password", validators=[DataRequired()]) submit = SubmitField('Submit')

UserMixin

# Inherit all necessary methods from UserMixin classclass User(UserMixin, db.Model):
def __init__(self, username, password, email):    self.username = username    # self.password = generate_password_hash(password)    # Hash the password when immediately registered    # Hash the password when immediately registered    self.password = password    self.email = email
def verify_password(self, pwd):    return check_password_hash(self.password, pwd)
# app.py...# Inherit all necessary methods from UserMixin classclass User(UserMixin, db.Model):    """Create columns to store our data"""    id = db.Column(db.Integer, primary_key=True)    username = db.Column(db.String(60), unique=True, nullable=False)    password = db.Column(db.String(20), unique=True, nullable=False)    email = db.Column(db.String(60), unique=True, nullable=False)    def __init__(self, username, password, email):        self.username = username        self.password = password        self.email = email    def __repr__(self):        return '<User %r>' % self.username    def verify_password(self, pwd):        return check_password_hash(self.password, pwd)...

Login Function

from form import LoginForm
from werkzeug.security import generate_password_hash, check_password_hash # New
from flask import Flask, render_template, request, redirect, url_for, flash, url_for # New
# app.py...@app.route("/login", methods=["GET", "POST"])def login():    # Create an object called "form" to use LoginForm class    form = LoginForm()    username = form.username.data    password = form.password.data
# Validate a form submitted by a user if form.validate_on_submit():

# Query a user's username from the database
user = User.query.filter_by(username=username).first()
# Check and compare a user's password # in a database, if True, log a user in if user and user.verify_password(password):
# Log a user in after completing verifying a password # then flash a message "Successful Login" login_user(user) flash("Successful Login")
# Redirect to homepage return redirect(url_for('home'))
else: # Show flash message "Invalid Login" if login gets False flash("Invalid Login") else: # You can print or return something such as an error message # In this case, do nothing. But you can do it later pass
return render_template('login.html', form=form)...
ต้องกำหนด SECRET_kEY

SECRET_KEY

# app.py...# Hard coded secret key for development onlyapp.config['SECRET_KEY'] = "your-secret-key-here" ...

การ Genarate ตัว SECRET_KEY มาใช้งาน

<!-- login.html -->
...
<form action="{{ url_for('login') }}" method="POST"> {{ form.csrf_token }} ...
</form>
...

HTML

{% if current_user.is_authenticated %}
  • เงื่อนไข 1 (if) ถ้าเป็นจริง ๆ คือ ถ้า User มีการล็อกอินเข้ามา และได้เป็นผู้ใช้ที่ยืนยันตัวตนเรียบร้อยแล้ว (Authenticated User) ให้แสดงชื่อผู้ใช้ เช่น ถ้าผู้ใช้ที่ล็อกอินเข้ามาชื่อ Sonny ก็จะปรากฏข้อความ Hi Sonny
Hi {{ current_user.username }}!
  • เงื่อนไข 2 (else) ถ้าไม่มีการล็อกอินเข้ามาให้แสดงข้อความ “Not authenticated now
<!-- base.html --><!--Create link to show, user is authenticated or not--><li class="nav-item">    <a class="nav-link" href="#" style="color: aqua; font-weight: bold;">        {% if current_user.is_authenticated %}     Hi {{ current_user.username }}!        {% else %}     Not authenticated now        {% endif %}    </a></li>
เพิ่มแสดงผลสถานะของผู้ใช้ว่าได้าล็อกอินเข้ามาหรือยัง
ยังไม่ได้ล็อกอิน
User มีการล็อกอินเข้าใช้งานเรียบร้อยแล้ว

ทบทวน

ฟังก์ชันที่ได้อิมพอร์ตเข้ามาในโปรเจคท์เพิ่มในวันนี้

สำหรับ Flask-Login Ep.2 ก็ขอจบลงเพียงเท่านี้ครับ ถ้ามีคำถามหรือข้อสงสัยหรือไม่เข้าใจตรงไหนก็คอมเมนต์ได้ที่ด้านล่างบทความกันได้เลยครับ หรือถ้าอยากติชมหรือมีอะไรเสนอแนะก็คอมเมนต์เข้ามาได้เช่นกันครับ

ท่านสามารถติดตามพวกเราได้ที่ stackpython ตามช่องทางด้านล่างนี้ได้เลยครับ

--

--

--

Full Stack Python Developers

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
stackpython

stackpython

Full Stack Python Developers

More from Medium

browser screenshot api

My Journey started with DLithe for Java Full Stack Developer.

Version Controlling System ,GIT, Mongo DB

ZIP file