Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Tạo ứng dụng web từ Scratch bằng Python Flask và MySQL:Phần 2

Trong phần trước của loạt bài này, chúng ta đã biết cách bắt đầu với Python Flask và MySQL và triển khai phần đăng ký người dùng của ứng dụng của chúng tôi. Trong hướng dẫn này, chúng tôi sẽ đưa điều này lên cấp độ tiếp theo bằng cách triển khai chức năng đăng nhập và đăng xuất cho ứng dụng của chúng tôi.

Bắt đầu

Đầu tiên sao chép mã nguồn của hướng dẫn trước từ GitHub.

git clone https://github.com/tutsplus/create-a-web-app-from-scratch-using-python-flask-and-mysql/.git

Khi mã nguồn đã được sao chép, hãy điều hướng đến phần 1 thư mục và khởi động máy chủ.

python app.py

Trỏ trình duyệt của bạn đến https:// localhost:5000 và bạn sẽ có ứng dụng đang chạy.

Tạo giao diện đăng nhập

Điều hướng đến FlaskApp / mẫu và tạo một tệp mới có tên signin.html . Mở signin.html và thêm mã HTML sau:

<!DOCTYPE html>
<html lang="en">
    <head>
		    
		<title>Python Flask Bucket List App - Sign In</title>
		    
		<link
			href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
			rel="stylesheet"
			integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"
			crossorigin="anonymous"
		/>
		<link href="../static/signup.css" rel="stylesheet" />
	</head>

	<body>
		    
		<div class="container">
			        
			<div class="header">
				            
				<nav
					class="border-bottom flex-wrap mb-4 py-3 d-flex justify-content-center"
				>
					<a
						href="/"
						class="text-dark text-decoration-none mb-3 mb-md-0 d-flex align-items-center me-md-auto"
					>
						<span class="fs-4">Python Flask App</span>
					</a>

					<ul class="nav nav-pills">
						<li class="nav-item">
							<a href="/" class="nav-link">Home</a>
						</li>
						<li class="nav-item">
							<a href="/signup" class="nav-link">Signup</a>
						</li>
						<li class="nav-item">
							<a href="/signin" class="nav-link active" aria-current="page"
								>Sign In</a
							>
						</li>
					</ul>
					                        
				</nav>
				        
			</div>
			<div class="bg-light rounded-3 mb-4 p-5">
				<div class="container-fluid py-5">
					<h1 class="text-center fw-bold display-5">Bucket List App</h1>
					<form class="form-signin" action="/api/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>&copy; Company 2022</p>
				        
			</footer>

			    
		</div>

	</body>
</html>

Mở app.py và thêm một tuyến đường mới cho giao diện đăng nhập.

@app.route('/signin')
def showSignin():
    return render_template('signin.html')

Tiếp theo, mở index.html signup.html và thêm href liên kết để đăng nhập trên cả hai trang với tư cách /signin . Lưu tất cả các thay đổi và khởi động lại máy chủ.

python app.py

Trỏ trình duyệt của bạn tới http:// localhost:5000 và nhấp vào nút Đăng nhập và bạn sẽ có thể xem trang đăng nhập.

Triển khai đăng nhập

Bây giờ, chúng ta cần tạo một hàm để xác thực thông tin đăng nhập của người dùng. Khi nhấp vào Đăng nhập , chúng tôi sẽ đăng địa chỉ email và mật khẩu đã nhập vào chức năng xác thực người dùng.

Tạo một thủ tục được lưu trữ

Để xác thực người dùng, chúng tôi sẽ cần một thủ tục được lưu trữ trong MySQL. Vì vậy, hãy tạo một thủ tục được lưu trữ MySQL như được hiển thị:

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 tôi sẽ lấy thông tin chi tiết về người dùng dựa trên username từ cơ sở dữ liệu MySQL bằng sp_validateLogin . Khi chúng tôi có mật khẩu được băm, chúng tôi sẽ xác thực nó dựa trên mật khẩu do người dùng nhập.

Xác thực Phương thức Người dùng

Tạo một phương thức để xác thực người dùng mà chúng tôi sẽ gọi khi người dùng gửi biểu mẫu:

@app.route('/api/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 mã trên, chúng tôi đã đọc địa chỉ email và mật khẩu được đăng thành _username_password . Bây giờ chúng ta sẽ gọi sp_validateLogin thủ tục với tham số _username . Vì vậy, hãy tạo một kết nối MySQL bên trong validatelogin phương pháp:

con = mysql.connect()

Khi kết nối đã được tạo, hãy tạo cursor sử dụng con kết nối.

cursor = con.cursor()

Sử dụng con trỏ, gọi thủ tục được lưu trữ MySQL như được hiển thị:

cursor.callproc('sp_validateLogin',(_username,))

Nhận các bản ghi đã tìm nạp từ con trỏ như được hiển thị:

data = cursor.fetchall()

Nếu dữ liệu có một số bản ghi, chúng tôi sẽ đối sánh mật khẩu đã truy xuất với mật khẩu do người dùng nhập.

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 mã trên, chúng tôi đã sử dụng một phương pháp có tên là check_password_hash để kiểm tra xem mật khẩu băm trả về có khớp với mật khẩu mà người dùng đã nhập hay không. Nếu tất cả đều tốt, thì chúng tôi 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 tôi sẽ hiển thị error.html với thông báo lỗi.

Đây là validateLogin đầy đủ mã:

@app.route('/api/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 trang có tên userhome.html bên trong thư mục mẫu và thêm mã HTML sau:

<!DOCTYPE html>
<html lang="en">
    <head>
		    
		<title>Python Flask Bucket List App - Home</title>
		    
		<link
			href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
			rel="stylesheet"
			integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"
			crossorigin="anonymous"
		/>
	</head>

	<body>
		    
		<div class="container">
			        
			<div class="header">
				            
				<nav
					class="border-bottom flex-wrap mb-4 py-3 d-flex justify-content-center"
				>
					<a
						href="/"
						class="text-dark text-decoration-none mb-3 mb-md-0 d-flex align-items-center me-md-auto"
					>
						<span class="fs-4">Python Flask App</span>
					</a>

					<ul class="nav nav-pills">
						<li class="nav-item">
							<a href="/userhome" class="nav-link">Home</a>
						</li>
						<li class="nav-item">
							<a href="/logout" class="nav-link active">Logout</a>
						</li>
					</ul>
					                        
				</nav>
				        
			</div>
			<div class="bg-light rounded-3 mb-4 p-5">
				<div class="container-fluid py-5">
					<h1 class="text-center fw-bold display-5">Welcome Home!</h1>
				</div>
			</div>
			        
			<footer class="footer">
				            
				<p>&copy; Company 2022</p>
				        
			</footer>

			    
		</div>
	</body>
</html>

Ngoài ra, hãy tạo một trang lỗi có tên error.html trong templates và thêm mã HTML sau:

<!DOCTYPE html>
<html lang="en">
    <head>
		    
		<title>Error - Python Flask App</title>
		    
		<link
			href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
			rel="stylesheet"
			integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"
			crossorigin="anonymous"
		/>
	</head>

	<body>
		    
		<div class="container">
			        
			<div class="header">
				            
				<nav
					class="border-bottom flex-wrap mb-4 py-3 d-flex justify-content-center"
				>
					<a
						href="/"
						class="text-dark text-decoration-none mb-3 mb-md-0 d-flex align-items-center me-md-auto"
					>
						<span class="fs-4">Python Flask App</span>
					</a>

					<ul class="nav nav-pills">
						<li class="nav-item">
							<a href="/" class="nav-link">Home</a>
						</li>
						<li class="nav-item">
							<a href="/signup" class="nav-link">Signup</a>
						</li>
						<li class="nav-item">
							<a href="/signin" class="nav-link">Sign In</a>
						</li>
					</ul>
					                        
				</nav>
				        
			</div>
			<div class="bg-light rounded-3 mb-4 p-5">
				<div class="container-fluid py-5">
					<h1 class="text-center fw-bold display-5">{{error}}</h1>
				</div>
			</div>
			        
			<footer class="footer">
				            
				<p>&copy; Company 2022</p>
				        
			</footer>

			    
		</div>
	</body>
</html>

Inside error.html , chúng tôi có một phần tử như được hiển thị:

<h1 class="text-center fw-bold display-5">{{error}}</h1>

Giá trị cho biến có thể được chuyển từ render_template và có thể được đặt động.

Khi đăng nhập thành công, chúng tôi đang chuyển hướng người dùng đến trang chủ của người dùng, vì vậy chúng tôi cần tạo một tuyến có tên /userHome như hình:

@app.route('/userHome')
def userHome():
    return render_template('userHome.html')
    

Lưu tất cả các thay đổi và khởi động lại máy chủ. Nhấp vào nút Đăng nhập liên kết trên trang chủ và cố gắng đăng nhập bằng địa chỉ email và mật khẩu hợp lệ. Khi xác thực người dùng thành công, bạn sẽ có một trang như được hiển thị bên dưới:

Khi xác thực người dùng không thành công, người dùng sẽ được chuyển hướng đến trang lỗi như được hiển thị bên dưới:

Ở đây chúng tôi đã 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ủ Người dùng

Khi xác thực người dùng thành công, người dùng được chuyển hướng đến trang chủ của người dùng. Nhưng ngay bây giờ, ngay cả người dùng trái phép cũng có thể xem trang chủ bằng cách duyệt qua URL http:// localhost:5000 / userhome.

Để hạn chế quyền truy cập trái phép của người dùng, chúng tôi sẽ kiểm tra một biến phiên mà chúng tôi sẽ đặt khi người dùng đăng nhập thành công. Vì vậy, hãy nhập session từ bình:

from flask import session

Chúng ta cũng cần đặt khóa bí mật cho phiên. Vì vậy, trong app.py , sau khi ứng dụng đã được khởi chạy, hãy đặt khóa bí mật như được hiển thị:

app.secret_key = 'why would I tell you my secret key?'

Bây giờ, bên trong validateLogin trước khi chuyển hướng người dùng đến /userhome khi đăng nhập thành công, hãy đặt session biến như hình:

session['user'] = data[0][0]

Tiếp theo, bên trong userhome , hãy kiểm tra biến phiên trước khi hiển thị userhome.html . Nếu không tìm thấy biến phiên, hãy chuyển hướng đến trang 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ả các thay đổi và khởi động lại máy chủ. Nếu không đăng nhập, hãy cố gắng điều hướng đến http:// localhost:5000 / userhome và vì bạn chưa đăng nhập, bạn sẽ được chuyển hướng đến trang lỗi.

Thực hiện Đăng xuất

Thực hiện chức năng đăng xuất là đơn giản nhất. Tất cả những gì chúng ta cần làm là tạo biến phiên user null và chuyển hướng người dùng đến trang chính.

Bên trong app.py , tạo một lộ trình và phương thức mới cho logout như hình:

@app.route('/logout')
def logout():
    session.pop('user',None)
    return redirect('/')

Chúng tôi đã đặt href cho nút đăng xuất thành /logout . Vì vậy, hãy lưu tất cả các thay đổi và khởi động lại máy chủ. Từ trang chủ, nhấp vào Đăng nhập và cố gắng đăng nhập bằng địa chỉ email và mật khẩu hợp lệ. Sau khi bạn đã đăng nhập, hãy nhấp vào nút Đăng xuất trong trang chủ của người dùng và bạn sẽ đăng xuất thành công khỏi ứng dụng.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. CHÈN VÀO ... CHỌN cho tất cả các cột MySQL

  2. Làm cách nào để tạo id duy nhất trong MySQL?

  3. Cách sử dụng động nhiều cơ sở dữ liệu cho một mô hình trong CakePHP

  4. Sử dụng tham số giới hạn nhiều lần

  5. Kiểm tra hiệu suất sử dụng MySQLdump và MySQL Shell Utility