使用 python flask-login 登录循环
login loop with python flask-login
我正在学习使用 flask-login class。这是一个介绍 class,我们没有在本练习中使用数据库,而是将凭据(散列)存储在 resing 文件中。我能够验证用户凭据,但是当用户 'successfully' 登录时,我没有重定向到受保护的 URL,而是被重定向到登录页面。
代码:
用户模型:
class User(UserMixin):
def __repr__(self):
return '<User{}>'.format(self)
def __init__(self):
self.username = None
self.email = None
self.password = None
self.user_id = None
def get_id(self):
return self.user_id
登录管理器:
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = "login"
@login_manager.user_loader
def load_user():
return User
登录部分:
user = User()
login_user(user)
return redirect(url_for('main'))
在我阅读的所有教程中,都使用了 sql 数据库。因为我们没有使用它,并且因为我根本不需要登录用户是特定的 - 只是为了通过身份验证,所以我正在阅读的很多内容在参数范围内都是行不通的。
您在定义用户加载器时忘记了一些东西。该函数采用 user_id
参数和 returns class 用户的对象,而不是 class 本身。 (参见 documentation)
下面的简化示例向您展示了不使用数据库实现的可能性。
基本上,flask-login 将用户对象的属性 id 存储在会话 cookie 中。基于此 id,相应的用户由数据库中的 LoginManager 查询,此处已由 class 变量/列表 users
.
替换
数据库实现通常有一个 id 列,它被定义为对于条目是唯一的。在示例中,唯一的 id of the object 用作替代。这意味着 mixin 的 getter 将被覆盖。所以这个例子保留了一个创建的用户对象的列表。在这些用户中可以通过他们的 ID 或用户名找到。
烧瓶 (app.py)
from flask import (
Flask,
redirect,
render_template,
request,
url_for
)
from flask_login import (
LoginManager,
UserMixin,
login_required,
login_user,
logout_user
)
class User(UserMixin):
def __init__(self, username, password):
self.username = username
self.password = password
self.__class__.users.append(self)
def get_id(self):
return id(self)
users = []
@classmethod
def get(cls, user_id):
for usr in cls.users:
if usr.get_id() == user_id:
return usr
return None
@classmethod
def find_by_username(cls, username):
for usr in cls.users:
if usr.username == username:
return usr
return None
app = Flask(__name__)
app.secret_key = 'your secret here'
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
@login_manager.user_loader
def load_user(user_id):
return User.get(user_id)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/register', methods=['GET', 'POST'])
def register():
keys = ('username', 'password')
if request.method == 'POST' and all(k in request.form for k in keys):
username = request.form['username']
password = request.form['password']
if User.find_by_username(username) is None:
User(username, password)
return redirect(url_for('.login'))
return render_template('register.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
user = User.find_by_username(username)
if user and user.password == password:
login_user(user)
return redirect(request.args.get('next', url_for('.index')))
return render_template('login.html')
@app.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('.index'))
@app.route('/secret')
@login_required
def secret():
return 'You found the secret.'
HTML (templates/index.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Index</title>
</head>
<body>
{% if current_user.is_authenticated -%}
<a href="{{ url_for('logout') }}">Logout</a>
{% else -%}
<a href="{{ url_for('register') }}">Register</a> |
<a href="{{ url_for('login') }}">Login</a>
{% endif -%}
<h1>Index</h1>
{% if current_user.is_authenticated -%}
Welcome {{ current_user.username }}!
{% else -%}
Welcome Guest!
{% endif -%}
</body>
</html>
HTML (templates/login.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Login</title>
</head>
<body>
<a href="{{ url_for('register') }}">Register</a>
<h1>Login</h1>
<form method="post">
<input type="text" name="username" placeholder="username" />
<input type="password" name="password" placeholder="password" />
<input type="submit" />
</form>
</body>
</html>
HTML (templates/register.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Register</title>
</head>
<body>
<h1>Register</h1>
<form method="post">
<input type="text" name="username" placeholder="username" />
<input type="password" name="password" placeholder="password" />
<input type="submit" />
</form>
</body>
</html>
我正在学习使用 flask-login class。这是一个介绍 class,我们没有在本练习中使用数据库,而是将凭据(散列)存储在 resing 文件中。我能够验证用户凭据,但是当用户 'successfully' 登录时,我没有重定向到受保护的 URL,而是被重定向到登录页面。 代码: 用户模型:
class User(UserMixin):
def __repr__(self):
return '<User{}>'.format(self)
def __init__(self):
self.username = None
self.email = None
self.password = None
self.user_id = None
def get_id(self):
return self.user_id
登录管理器:
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = "login"
@login_manager.user_loader
def load_user():
return User
登录部分:
user = User()
login_user(user)
return redirect(url_for('main'))
在我阅读的所有教程中,都使用了 sql 数据库。因为我们没有使用它,并且因为我根本不需要登录用户是特定的 - 只是为了通过身份验证,所以我正在阅读的很多内容在参数范围内都是行不通的。
您在定义用户加载器时忘记了一些东西。该函数采用 user_id
参数和 returns class 用户的对象,而不是 class 本身。 (参见 documentation)
下面的简化示例向您展示了不使用数据库实现的可能性。
基本上,flask-login 将用户对象的属性 id 存储在会话 cookie 中。基于此 id,相应的用户由数据库中的 LoginManager 查询,此处已由 class 变量/列表 users
.
替换
数据库实现通常有一个 id 列,它被定义为对于条目是唯一的。在示例中,唯一的 id of the object 用作替代。这意味着 mixin 的 getter 将被覆盖。所以这个例子保留了一个创建的用户对象的列表。在这些用户中可以通过他们的 ID 或用户名找到。
烧瓶 (app.py)
from flask import (
Flask,
redirect,
render_template,
request,
url_for
)
from flask_login import (
LoginManager,
UserMixin,
login_required,
login_user,
logout_user
)
class User(UserMixin):
def __init__(self, username, password):
self.username = username
self.password = password
self.__class__.users.append(self)
def get_id(self):
return id(self)
users = []
@classmethod
def get(cls, user_id):
for usr in cls.users:
if usr.get_id() == user_id:
return usr
return None
@classmethod
def find_by_username(cls, username):
for usr in cls.users:
if usr.username == username:
return usr
return None
app = Flask(__name__)
app.secret_key = 'your secret here'
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
@login_manager.user_loader
def load_user(user_id):
return User.get(user_id)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/register', methods=['GET', 'POST'])
def register():
keys = ('username', 'password')
if request.method == 'POST' and all(k in request.form for k in keys):
username = request.form['username']
password = request.form['password']
if User.find_by_username(username) is None:
User(username, password)
return redirect(url_for('.login'))
return render_template('register.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
user = User.find_by_username(username)
if user and user.password == password:
login_user(user)
return redirect(request.args.get('next', url_for('.index')))
return render_template('login.html')
@app.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('.index'))
@app.route('/secret')
@login_required
def secret():
return 'You found the secret.'
HTML (templates/index.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Index</title>
</head>
<body>
{% if current_user.is_authenticated -%}
<a href="{{ url_for('logout') }}">Logout</a>
{% else -%}
<a href="{{ url_for('register') }}">Register</a> |
<a href="{{ url_for('login') }}">Login</a>
{% endif -%}
<h1>Index</h1>
{% if current_user.is_authenticated -%}
Welcome {{ current_user.username }}!
{% else -%}
Welcome Guest!
{% endif -%}
</body>
</html>
HTML (templates/login.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Login</title>
</head>
<body>
<a href="{{ url_for('register') }}">Register</a>
<h1>Login</h1>
<form method="post">
<input type="text" name="username" placeholder="username" />
<input type="password" name="password" placeholder="password" />
<input type="submit" />
</form>
</body>
</html>
HTML (templates/register.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Register</title>
</head>
<body>
<h1>Register</h1>
<form method="post">
<input type="text" name="username" placeholder="username" />
<input type="password" name="password" placeholder="password" />
<input type="submit" />
</form>
</body>
</html>