flask 模拟简单的登录功能(2)

通过设置 app.secret_key 进行用户登录验证

通过使用app.secret_key,可以对会话数据进行加密和解密,以确保会话数据的安全性。会话数据包括用户的登录状态、表单数据等敏感信息,通过设置 app.secret_key,可以防止会话被恶意篡改或窃取。
app.py代码如下:

python 复制代码
from flask import Flask, request, session, redirect, url_for,render_template

app = Flask(__name__)
app.secret_key = 'your_secret_key'

# 模拟用户数据库
users = {
    'admin': 'admin'
}

# 根路径
@app.route('/')
def index():
    if 'logged_in' in session and session['logged_in']:
        return redirect(url_for('page'))
    else:
        return render_template('login2.html')
        
@app.route('/login', methods=['POST','GET'])
def login():
    print(request.method)
    if request.method == 'POST':
        print('post')
        username = request.form['username']
        password = request.form['password']
        if users.get(username) == password:
            session['logged_in'] = True
            return redirect(url_for('success'))
        else:
            return redirect(url_for('failed'))
    else:
        print('get')
        if 'logged_in' in session and session['logged_in']:
            return redirect(url_for('success'))
        return redirect(url_for('goto'))

# 登录成功
@app.route('/success')
def success():
    return f'login successfully!<a href = "/logout">退出登录</a>'

# 登录失败
@app.route('/failed')
def failed():
    return f'login failed!<a href = "/">重新登录</a>'

# 登录失败
@app.route('/goto')
def goto():
    return f'Please login first!<a href = "/">去登录</a>'
    
# 退出登录
@app.route('/logout')
def logout():
    session.pop('logged_in', None)
    return 'Logged out,<a href = "/">点击重新登录</a>'

@app.route('/page')
def page():
    if 'logged_in' in session:
        return '这是授权页内容,<a href = "/logout">退出登录</a>'
    else:
        return redirect(url_for('login'))

if __name__ == '__main__':
    app.run()

login.html 页面入下:

html 复制代码
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
    <form action="http://localhost:5000/login" method="post">
        <table>
            <tr>
                <td>Username</td>
                <td><input type="username" name="username"></td>
            </tr>
            <tr>
                <td>Password</td>
                <td><input type="password" name="password"></td>
            </tr>
            <tr>
                <td><input type="submit" value="Submit"></td>
            </tr>
        </table>
    </form>
    {% if error %}
    <p><strong>Error</strong>:{{error}}</p>
    {% endif %}
</body>
</html>

在上面的例子中,通过 POST 请求 /login 路由来接收用户提交的用户名和密码,并在用户登录成功时将 logged_in 标记设置为 True,表示用户已经登录。然后,在访问 /page 路由时,检查用户是否已登录,如果未登录则提示去登录。

注意,当我们在浏览器中点击登录按钮,表单通过 POST 请求提交到 /login 路由,如果登录成功,直接reurn 'Login successful'这样写的话,页面一开始进去显示 "Login successful",此时,如果在浏览器中直接进行页面刷新(比如按下 F5 键),浏览器会重新发送上一次的请求。如果上一次的请求是一个 POST 请求,那么刷新操作也会发送一个相同的 POST 请求,而不是一个 GET 请求。这是因为浏览器的刷新操作会重复最后一次的请求,不论它是 GET 请求还是 POST 请求。对于 POST 请求,许多浏览器会显示一个对话框,警告用户刷新页面将会重新提交表单。如果用户选择继续,浏览器就会再次发送 POST 请求到服务器。

为了避免在登录成功后直接刷新页面导致再次发送 POST 请求的问题,在这里我们 POST 请求并完成相关操作(比如用户登录)后,进行一个重定向操作到另一个页面或路由。这种方法被称为 Post/Redirect/Get (PRG) 模式,它可以防止表单的重复提交。

这只是一个简单的示例,实际应用中用户登录验证可能会更加复杂,包括密码哈希存储、用户会话管理等。对于更复杂的用户认证需求,建议使用 Flask 提供的认证扩展或其他第三方库来实现。

相关推荐
子兮曰21 小时前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰21 小时前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
默_笙21 小时前
🍙 给每个请求过安检:FastAPI 是怎么把校验写进类型注解的
python
爱勇宝21 小时前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
qq_4260039621 小时前
启动playwright录制codegen生成自动化测试脚本
python·自动化
虎头金猫21 小时前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
胡写代码21 小时前
别再前后端各写一套表单校验了
java·后端
长沙三为智能科技1 天前
家政小程序开发从0到上线:五阶段交付流程与验收清单
python
伞伞悦读1 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
大勇前进1 天前
原生 PHP 还是 Laravel?小项目到底要不要上框架
后端