Vietnamese (Tiếng Việt) translation by Dai Phong (you can also view the original English article)
Trong phần trước của loạt bài này, chúng ta đã biết cách làm thế nào để bắt đầu với Python Flask và MySQL và cài đặt phần đăng ký người dùng của ứng dụng. Trong hướng dẫn này, chúng ta sẽ nâng nó lên một cấp độ cao hơn bằng cách cài đặt tính năng đăng nhập và đăng xuất cho ứng dụng của chúng ta.
Bắt đầu
Đầu tiên clone mã nguồn của hướng dẫn trước từ GitHub.
git clone https://github.com/jay3dec/PythonFlaskMySQLApp---Part-1.git
Một khi mã nguồn đã được clone, điều hướng đến thư mục PythonFlaskMySQLApp---Part-1
và khởi động máy chủ.
python app.py
Trỏ trình duyệt đến http://localhost:5002 và bạn sẽ thấy ứng dụng đang chạy.
Tạo Giao diện Đăng nhập
Điều hướng đến PythonFlaskMySQLApp---Part-1/templates
và tạo một tập tin mới có tên signin.html
. Mở signin.html
và thêm code HTML sau đây:
<!DOCTYPE html> <html lang="en"> <head> <title>Python Flask Bucket List App</title> <link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet"> <link href="http://getbootstrap.com/examples/jumbotron-narrow/jumbotron-narrow.css" rel="stylesheet"> <link href="../static/css/signup.css" rel="stylesheet"> <script src="../static/js/jquery-1.11.2.js"></script> </head> <body> <div class="container"> <div class="header"> <nav> <ul class="nav nav-pills pull-right"> <li role="presentation" ><a href="/">Home</a></li> <li role="presentation" class="active"><a href="#">Sign In</a></li> <li role="presentation" ><a href="/showSignUp">Sign Up</a></li> </ul> </nav> <h3 class="text-muted">Python Flask App</h3> </div> <div class="jumbotron"> <h1>Bucket List App</h1> <form class="form-signin" action="/validateLogin" method="post"> <label for="inputEmail" class="sr-only">Email address</label> <input type="email" name="inputEmail" id="inputEmail" class="form-control" placeholder="Email address" required autofocus> <label for="inputPassword" class="sr-only">Password</label> <input type="password" name="inputPassword" id="inputPassword" class="form-control" placeholder="Password" required> <button id="btnSignIn" class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button> </form> </div> <footer class="footer"> <p>© Company 2015</p> </footer> </div> </body> </html>
Mở app.py
và thêm một tuyến (route) mới cho giao diện đăng nhập.
@app.route('/showSignin') def showSignin(): return render_template('signin.html')
Tiếp theo, mở index.html
và signup.html
, và thêm liên kết href
cho đăng nhập trên cả hai trang là /showSignin
. Lưu tất cả những thay đổi và khởi động lại máy chủ.
python app.py
Trỏ trình duyệt tới http://localhost:5002 và nhấp vào liên kết Sign In, và bạn sẽ có thể thấy trang đăng nhập.



Cài đặt Đăng nhập
Bây giờ, chúng ta cần phải tạo ra hàm để xác nhận đăng nhập người dùng. Khi nhấp vào Sign In chúng ta sẽ post địa chỉ email và mật khẩu đã nhập vào hàm kiểm tra người dùng.
Tạo một Thủ tục Lưu trữ
Để kiểm tra một người dùng, chúng ta sẽ cần một thủ tục lưu trữ MySQL. Vì vậy, hãy tạo một thủ tục lưu trữ MySQL như sau:
DELIMITER $$ CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_validateLogin`( IN p_username VARCHAR(20) ) BEGIN select * from tbl_user where user_username = p_username; END$$ DELIMITER ;
Chúng ta sẽ lấy các chi tiết của người dùng dựa trên username
từ cơ sở dữ liệu MySQL sủ dụng sp_validateLogin
. Một khi chúng ta đã có mật khẩu băm, chúng ta sẽ xác nhận nó với mật khẩu được nhập vào bởi người dùng.
Kiểm tra Phương thức Người dùng
Tạo một phương thức để kiểm tra người dùng mà chúng ta sẽ gọi khi người dùng submit form:
@app.route('/validateLogin',methods=['POST']) def validateLogin(): try: _username = request.form['inputEmail'] _password = request.form['inputPassword'] except Exception as e: return render_template('error.html',error = str(e))
Như đã thấy trong đoạn code ở trên, chúng ta đã đọc địa chỉ email và mật khẩu được post lên vào _username
và _password
. Bây giờ chúng ta sẽ gọi thủ tục sp_validateLogin
với tham số _username
. Vì vậy, hãy tạo một kết nối MySQL bên trong phương thức validateLogin
:
con = mysql.connect()
Khi kết nối đã được tạo ra, hãy tạo một cursor
bằng cách sử dụng kết nối con
.
cursor = con.cursor()
Sử dụng cursor, hãy gọi thủ tục lưu trữ MySQL như sau:
cursor.callproc('sp_validateLogin',(_username,))
Lấy các record từ cursor như sau:
data = cursor.fetchall()
Nếu dữ liệu có một số record, chúng ta sẽ khớp mật khẩu lấy được với mật khẩu nhập vào bởi người dùng.
if len(data) > 0: if check_password_hash(str(data[0][3]),_password): return redirect('/userHome') else: return render_template('error.html',error = 'Wrong Email address or Password.') else: return render_template('error.html',error = 'Wrong Email address or Password.')
Như đã thấy trong đoạn code ở trên, chúng ta đã sử dụng một phương thức gọi là check_password_hash
để kiểm tra xem mật khẩu băm trả về có trùng với mật khẩu được nhập vào bởi người dùng hay không. Nếu tất cả đều ổn thì chúng ta sẽ chuyển hướng người dùng đến userHome.html
. Và nếu có bất kỳ lỗi nào, chúng ta sẽ hiển thị error.html
với thông báo lỗi.
Dưới đây là code hoàn chỉnh cho validateLogin
:
@app.route('/validateLogin',methods=['POST']) def validateLogin(): try: _username = request.form['inputEmail'] _password = request.form['inputPassword'] # connect to mysql con = mysql.connect() cursor = con.cursor() cursor.callproc('sp_validateLogin',(_username,)) data = cursor.fetchall() if len(data) > 0: if check_password_hash(str(data[0][3]),_password): session['user'] = data[0][0] return redirect('/userHome') else: return render_template('error.html',error = 'Wrong Email address or Password.') else: return render_template('error.html',error = 'Wrong Email address or Password.') except Exception as e: return render_template('error.html',error = str(e)) finally: cursor.close() con.close()
Tạo một trang gọi là userHome.html
bên trong thư mục templates và thêm code HTML sau đây:
<!DOCTYPE html> <html lang="en"> <head> <title>Python Flask Bucket List App</title> <link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet"> <link href="http://getbootstrap.com/examples/jumbotron-narrow/jumbotron-narrow.css" rel="stylesheet"> <link href="../static/css/signup.css" rel="stylesheet"> </head> <body> <div class="container"> <div class="header"> <nav> <ul class="nav nav-pills pull-right"> <li role="presentation" class="active"><a href="/logout">Logout</a> </li> </ul> </nav> <h3 class="text-muted">Python Flask App</h3> </div> <div class="jumbotron"> <h1>Welcome Home !!</h1> </div> <footer class="footer"> <p>© Company 2015</p> </footer> </div> </body> </html>
Đồng thời tạo một trang lỗi được gọi là error.html
trong thư mục templates
và thêm code HTML sau đây:
<!DOCTYPE html> <html lang="en"> <head> <title>Unauthorized Access:: Python Flask Bucket List App</title> <link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet"> <link href="http://getbootstrap.com/examples/jumbotron-narrow/jumbotron-narrow.css" rel="stylesheet"> </head> <body> <div class="container"> <div class="header"> <nav> <ul class="nav nav-pills pull-right"> <li role="presentation" class="active"><a href="#">Home</a> </li> <li role="presentation"><a href="/showSignin">Sign In</a> </li> <li role="presentation"><a href="/showSignUp">Sign Up</a> </li> </ul> </nav> <h3 class="text-muted">Python Flask App</h3> </div> <div class="jumbotron"> <h1>{{error}}</h1> </div> <footer class="footer"> <p>© Company 2015</p> </footer> </div> </body> </html>
Bên trong error.html
chúng ta có một phần tử như sau:
<h1>{{error}}</h1>
Giá trị cho biến có thể được truyền từ hàm render_template
và có thể được thiết lập tự động.
Khi đăng nhập thành công, chúng ta chuyển hướng người dùng đến trang chủ, vì vậy chúng ta cần phải tạo ra một tuyến có tên là /userHome
như sau:
@app.route('/userHome') def userHome(): return render_template('userHome.html')
Lưu tất cả những thay đổi và khởi động lại máy chủ. Nhấp vào liên kết Sign In trên trang chủ và thử đăng nhập bằng địa chỉ email và mật khẩu hợp lệ. Khi xác nhận người dùng thành công, bạn sẽ có một trang như hình dưới đây:



Khi xác nhận người dùng không thành công, người dùng sẽ được chuyển hướng đến một trang lỗi như hình dưới đây:



Ở đây, chúng ta sử dụng một trang lỗi riêng biệt để hiển thị lỗi. Cũng tốt nếu bạn muốn sử dụng cùng một trang để hiển thị thông báo lỗi.
Hạn chế Truy cập Trái phép vào Trang chủ của Người dùng
Khi xác nhận người dùng thành công thì một người dùng được chuyển hướng đến trang chủ của người dùng. Nhưng ngay lúc này, ngay cả một người dùng trái phép cũng có thể xem trang chủ chỉ đơn giản bằng cách truy cập địa chỉ http://localhost:5002/userHome.
Để hạn chế người dùng truy cập trái phép, chúng ta sẽ kiểm tra một biến session mà chúng ta sẽ thiết lập khi người dùng đăng nhập thành công. Do đó, hãy import session
từ flask:
from flask import session
Chúng ta cũng cần phải thiết lập một khóa bí mật cho session. Vì vậy, trong app.py
, sau khi ứng dụng đã được khởi tạo, hãy thiết lập khóa bí mật như sau:
app.secret_key = 'why would I tell you my secret key?'
Bây giờ, bên trong phương thức validateLogin
, trước khi chuyển hướng người dùng đến /userHome
khi đăng nhập thành công, thiết lập biến session
như sau:
session['user'] = data[0][0]
Tiếp theo, bên trong phương thức userHome
, kiểm tra biến session trước khi kết xuất userHome.html
. Nếu biến session không được tìm thấy, chuyển hướng đến trang báo lỗi.
@app.route('/userHome') def userHome(): if session.get('user'): return render_template('userHome.html') else: return render_template('error.html',error = 'Unauthorized Access')
Lưu tất cả những thay đổi và khởi động lại máy chủ. Không cần đăng nhập, hãy thử truy cập đến http://localhost:5002/userHome và vì bạn vẫn chưa đăng nhập vào, nên bạn sẽ được chuyển hướng đến trang lỗi.



Cài đặt Đăng xuất
Việc cài đặt tính năng đăng xuất là đơn giản nhất. Tất cả những gì chúng ta cần phải làm là làm cho biến session user
thành null và chuyển hướng người dùng đến trang chủ.
Bên trong app.py
, hãy tạo một tuyến mới và phương thức logout
như dưới đây:
@app.route('/logout') def logout(): session.pop('user',None) return redirect('/')
Chúng ta đã thiết lập href cho nút logout thành /logout
. Do đó, hãy lưu tất cả những thay đổi và khởi động lại máy chủ. Từ trang chủ, nhấp vào Sign In và thử đăng nhập bằng địa chỉ email và mật khẩu hợp lệ. Một khi đã đăng nhập, nhấn vào nút Logout trong trang người dùng và bạn sẽ đăng xuất thành công khỏi ứng dụng.
Tóm tắt
Trong phần này của hướng dẫn, chúng ta đã học được cách để cài đặt tính năng người dùng đăng nhập và đăng xuất. Chúng ta cũng đã thấy cách để hạn chế truy cập trái phép vào các trang ứng dụng. Trong phần tiếp theo của hướng dẫn này, chúng ta sẽ cài đặt tính năng để cho người dùng đã đăng nhập thêm và chỉnh sửa một phần tử trong ứng dụng.
Mã nguồn từ hướng dẫn này có sẵn trên GitHub.
Hãy cho chúng tôi biết những suy nghĩ của bạn trong phần bình luận dưới đây nhé!