flask 登入

boye169發表於2024-10-17
#!/usr/bin/env python
# encoding: utf-8
#pip install flask-login
import datetime
from flask import Flask, Blueprint,session, redirect, url_for, render_template, request
from flask_login import LoginManager,current_user, login_user, login_required, logout_user
from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash


class User(UserMixin):
    username = None

    def __init__(self,id,username,password_hash):
        self.id = id
        self.username = username
        self.set_password(password_hash)

    def get_id(self):
        return self.id
        
    def set_password(self, password):
        self.password_hash = generate_password_hash(password)

    def validate_password(self, password):
        return check_password_hash(self.password_hash, password)

UserData = {
        1 : User(
            id=1,
            username='admin',
            password_hash = 'admin'
        )
    } 
 
app = Flask(__name__)
 
app.secret_key = 's3cr3t'
login_manager = LoginManager()
 
# 設定不同的安全等級防止使用者會話遭篡改,屬性可以設為None、basic或strong
# 設為 strong 時,Flask-Login 會記錄客戶端 IP 地址和瀏覽器的使用者代理資訊,如果發現異動就登出使用者
login_manager.session_protection = 'strong' 
 
# 如果未登入,返回的頁面
login_manager.login_view = 'auth.login'
login_manager.init_app(app)
 
# Flask-Login 要求程式實現一個回撥函式,使用指定的識別符號載入使用者
@login_manager.user_loader
def load_user(user_id):
    return UserData.get(user_id)

 
auth = Blueprint('auth', __name__)


# 登入
@auth.get('/login')
def login():
    if current_user.is_authenticated: #判斷當前使用者是否是登入狀態
        return redirect(url_for('auth.index'))
    html ='''<!DOCTYPE html><html><head>
    <meta charset="utf-8"> 
    <title>登入頁面</title> 
</head><body>
<form action="/auth/login" method="post">
        <!-- 文字輸入框 -->
        <label for="username">使用者名稱:</label>
        <input type="text" id="username" name="username" required><br>
        <!-- 密碼輸入框 -->
        <label for="password">密碼:</label>
        <input type="password" id="password" name="password" required><br>
        <!-- 提交按鈕 -->
        <input type="submit" value="提交">
    </form>
</body>
</html>'''
    return html

# 登入
@auth.post('/login')
def login_post():
    try:
        req = request.form
        username = req.get('username')
        password = req.get('password')
        user = UserData.get(1)
        print(username,password)
        if not user:return '不存在的使用者'
        if username == user.username and user.validate_password(password):
            duration = datetime.timedelta(seconds=30*60) # 30*60秒
            remember = True
            # login_user(user, remember=remember) # 登入
            login_user(user)  # 建立使用者 Session
            # return "ok"
            return redirect(request.args.get('next') or url_for('auth.index'))
        else:
            return "密碼不正確"
    except Exception as e:
        print(e)
        return "error"
 
 
# 透過Flask-Login提供的login_required裝飾器來增加路由保護,如果未認證使用者訪問這個路由,Flask-Login會將這個請求發往登入頁面
@auth.route('/logout', methods=['GET', 'POST'])
@login_required
def logout():
    logout_user()
    return redirect(url_for('auth.login'))
 
 
# test method
@app.get('/')
@auth.get('/index')
@login_required
def index():
    return "<h1>This is the first page</h1><h4><a href='/auth/login'>登入</a></h4><a href='/auth/logout'>退出登入</a>"
 
if __name__ == "__main__": 
    app.register_blueprint(auth, url_prefix='/auth')
    app.run(debug=True,host='0.0.0.0',port=8080)

  

相關文章