플라스크 마개: 어떻게 작동하는지 이해할 수 없습니다.
어떻게 작동하는지 이해하려고 노력 중이야
문서에서 미리 입력된 사용자 목록을 사용하고 있는 것을 알 수 있습니다.데이터베이스에 저장된 사용자 목록을 가지고 놀고 싶습니다.
다만, 이 모듈의 내용을 이해할 수 없는 것이 있습니다.
@login_manager.user_loader
def load_user(userid):
#print 'this is executed',userid
return user(userid, 'asdf')
이 코드는 요청 시마다 호출됩니까?사용자 개체의 모든 세부 정보를 로드하는 데 사용됩니까?
지금으로서는, 다음과 같은 코드가 있습니다.
@app.route('/make-login')
def make_login():
username = 'asdf'
password = 'asdf'
user_data = authenticate(username, password)
user_obj = user(user_data[0], user_data[1])
login_user(user_obj)
return render_template('make-login.html')
/make-login에 접속하면 로그인하고 싶습니다.
내 사용자 클래스:
class user(object):
def __init__(self, id, username, active=True):
self.username = username
self.id = id
#self.active = active
def is_authenticated(self):
return True
def is_active(self):
return True
def is_anonymous(self):
return False
def get_id(self):
return 5
또한 인증/등록을 위한 두 가지 기능을 추가로 작성했습니다.
def authenticate(username, password):
cursor = db.cursor()
password = md5.md5(password).hexdigest()
try:
query = "SELECT * FROM `users` WHERE `username` = %s AND `password` = %s"
cursor.execute(query, (username, password))
results = cursor.fetchall()
#print results[0][0]
#print "here i am"
if not results:
return False
else:
user_data = [results[0][0], results[0][1]]
return user_data
#self.authenticated = True
#self.user_id = results[0][0]
#session['username'] = results['username']
#print type(results)
except db.Error, e:
return 'There was a mysql error'
def register(username, password, email, *args):
cursor = db.cursor()
password = md5.md5(password).hexdigest()
try:
#query = "INSERT INTO `users` (`username`, `password`, `email`) VALUES ('%s', '%s', '%s')" % (username, password, email)
query = "INSERT INTO `users` (`username`, `password`, `email`) VALUES (%s, %s, %s)"
cursor.execute(query, (username, password, email))
db.commit()
return True
except db.Error, e:
print 'An error has been passed. %s' %e
db.rollback()
return False
MySQL에서 어떻게 동작하는지 모르겠어요.또한 사용자가 로그인했는지 알 수 없습니다.사용자 ID 또는 사용자 이름을 얻으려면 어떻게 해야 하나요?
이게 어떻게 작동하는지 설명해 줄 사람?
Flask-login에는 실제로 사용자 백엔드가 없습니다.사용자의 로그인과 로그아웃을 지원하기 위해 세션 머신을 처리합니다.유저가 「액티브」인지 아닌지를 파악하는 방법( 「액티브」는 애플리케이션 마다 다른 것을 의미할 수 있기 때문에)은, 유저를 나타내는 것, 및 유저의 「액티브」인지 아닌지를 판단하는 방법에 의해서, 유저에게 지시할 필요가 있습니다.
매뉴얼을 읽고 그 기능과 기능을 확인해야 합니다.여기서는 db 백엔드를 사용한 배선에만 초점을 맞춥니다.
먼저 사용자의 속성을 나타내는 사용자 개체를 정의합니다.이 오브젝트는 데이터베이스, LDAP 등의 쿼리를 실행할 수 있으며 로그인 메커니즘과 데이터베이스 백엔드를 연결하는 후크입니다.
이 목적으로 로그인 예제 스크립트를 사용합니다.
class User(UserMixin):
def __init__(self, name, id, active=True):
self.name = name
self.id = id
self.active = active
def is_active(self):
# Here you should write whatever the code is
# that checks the database if your user is active
return self.active
def is_anonymous(self):
return False
def is_authenticated(self):
return True
사용자 오브젝트가 생성되면 사용자를 로드하는 메서드를 작성해야 합니다(기본적으로 사용자 오브젝트의 인스턴스를 만듭니다).User
위로부터의 클래스).이 메서드는 사용자 ID로 호출됩니다.
@login_manager.user_loader
def load_user(id):
# 1. Fetch against the database a user by `id`
# 2. Create a new object of `User` class and return it.
u = DBUsers.query.get(id)
return User(u.name,u.id,u.active)
다음의 순서를 실행하면, 로그인 방법에 의해서 다음과 같이 됩니다.
사용자 이름과 비밀번호가 (데이터베이스와) 일치하는지 확인합니다. 이 코드를 직접 작성해야 합니다.
인증에 성공한 경우 사용자의 인스턴스를 다음 주소로 전달합니다.
login_user()
Flask-login은 모든 요청 전에 사용자를 로드하려고 시도합니다.네, 아래의 예제 코드는 모든 요청 전에 호출됩니다.현재 세션에 어떤 사용자 ID가 있는지 확인하고 해당 ID의 사용자 개체를 로드합니다.
@login_manager.user_loader
def load_user(userid):
#print 'this is executed',userid
return user(userid, 'asdf')
github의 Flask-login 소스 코드를 보면 함수 init_app 아래에 다음과 같은 행이 있습니다.
app.before_request(self._load_user)
따라서 모든 요구 전에 _load_user 함수가 호출됩니다._load_user 함수는 실제로 조건에 따라 다른 함수 "reload_user()"를 호출합니다.마지막으로 reload_user() 함수는 작성한 콜백 함수(예에서는 load_user())를 호출합니다.
또한 플라스크 로그인은 사용자를 로그인/로그아웃하는 메커니즘만 제공합니다.mysql 데이터베이스를 사용해도 상관없습니다.
Flask-Login 문서에 따라 사용자 개체를 반환해야 하며 사용자 ID를 찾을 수 없는 경우 Exception 대신 None을 반환해야 합니다.
@login_manager.user_loader
def load_user(userid):
try:
#: Flask Peewee used here to return the user object
return User.get(User.id==userid)
except User.DoesNotExist:
return None
Flask-Security를 사용하면 데이터베이스 접근을 위해 Flask-Login과 SQL Chemy를 결합하여 사용자 레코드의 백엔드 처리를 대부분 자동화할 수 있습니다.
빠른 시작 튜토리얼을 통해 시작할 수 있습니다.app.config[']를 설정합니다.SQLALCHEMY_DATABASE_URI']를 MySQL 데이터베이스 연결 문자열에 연결합니다.
모든 설명이 끝나면 코드를 사용하여 간단한 사용 예를 제시함과 동시에 아래에 답변하겠습니다.
다음의 순서를 실행하면, 로그인 방법에 의해서 다음과 같이 됩니다.
- 사용자 이름과 비밀번호가 (데이터베이스와) 일치하는지 확인합니다. 이 코드를 직접 작성해야 합니다.
- 는, 를 「인스턴스」에 합니다.
login_user()
예를 들어 다음과 같이 프로젝트의 구조를 나타냅니다.
├─stackoverflow
│ run.py
│
└───site
│ forms.py
│ models.py
│ routes.py
│ site.db
│ __init__.py
│
├───static
│ main.css
│
└───templates
about.html
account.html
home.html
layout.html
login.html
register.html
가장 관심이 있는 것은 모델입니다.
# models.py
from site import db, login_manager
from flask_login import UserMixin
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
image_file = db.Column(db.String(20), nullable=False, default='default.jpg')
password = db.Column(db.String(60), nullable=False)
def __repr__(self):
return f"User('{self.username}', '{self.email}', '{self.image_file}')"
그리고 사용자 로그인으로 호출합니다.정확히는 사용자가 등록한 후에 호출합니다.사용자가 존재하는 후에 호출합니다.
구체적으로는, 실장할 필요가 있는 2개의 스텝에 대한 대답은, 다음의 2 행의 코드에서 확인할 수 있습니다.
- 사용자 이름과 비밀번호가 (데이터베이스와) 일치하는지 확인합니다. 이 코드를 직접 작성해야 합니다.
::if user and bcrypt.check_password_hash(user.password, form.password.data):
- 는, 를 「인스턴스」에 합니다.
login_user()
::login_user(user, remember=form.remember.data)
# routes.py
from flask import render_template, url_for, flash, redirect, request
from site import app, db, bcrypt
from site.forms import RegistrationForm, LoginForm
from site.models import User
from flask_login import login_user, current_user, logout_user, login_required
@app.route("/")
@app.route("/home")
def home():
return render_template('home.html', title="Welcome")
@app.route("/register", methods=['GET', 'POST'])
def register():
if current_user.is_authenticated:
return redirect(url_for('home'))
form = RegistrationForm()
if form.validate_on_submit():
hashed_password = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
user = User(username=form.username.data, email=form.email.data, password=hashed_password)
db.session.add(user)
db.session.commit()
flash('Your account has been created! You are now able to log in', 'success')
return redirect(url_for('login'))
return render_template('register.html', title='Register', form=form)
@app.route("/login", methods=['GET', 'POST'])
def login():
if current_user.is_authenticated:
return redirect(url_for('home'))
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
if user and bcrypt.check_password_hash(user.password, form.password.data):
login_user(user, remember=form.remember.data)
next_page = request.args.get('next')
return redirect(next_page) if next_page else redirect(url_for('home'))
else:
flash('Login Unsuccessful. Please check email and password', 'danger')
return render_template('login.html', title='Login', form=form)
# Views that require your users to be logged in can be decorated with the `login_required` decorator
@app.route("/account")
@login_required
def account():
return render_template('account.html', title='Account')
# When the user is ready to log out:
@app.route("/logout")
@login_required
def logout():
logout_user()
return redirect(url_for('home'))
는 로그인한 사용자에게 할 수 .current_user
「 」 「 」 、 「 」 、 「 」 。
{% if current_user.is_authenticated %}
Hi {{ current_user.username }}!
{% endif %}
을 했을 때login_required
Flask-Login 401 오류와 중단됩니다.)
은 '로그인하다'로 설정할 수.LoginManager.login_view
:
login_manager.login_view = 'login'
# __init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_login import LoginManager
app = Flask(__name__)
app.config['SECRET_KEY'] = 'ENTER_SECRET_KEY'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db = SQLAlchemy(app)
bcrypt = Bcrypt(app)
login_manager = LoginManager(app)
login_manager.login_view = 'login'
login_manager.login_message_category = 'info'
from site import routes
마지막으로 프로젝트를 실행합니다.
# run.py
from site import app
if __name__ == '__main__':
app.run(debug=True)
훌륭한 설명에 덧붙여, 이 간단한 예가 도움이 되었으면 합니다.
다음 Flask의 로그인 사용 예를 나타냅니다.https://bitbucket.org/leafstorm/flask-login/src/3160dbfc7cfc/example/login-example.py 로그인이 필요한 모든 메서드에 대해 @syslog_required를 사용해야 합니다.예를들면,
@app.route('/make-login')
@login_required
def make_login():
...
flask-login은 user_loader를 호출하여 요청별로 사용자 개체를 요구합니다.
매번 DB를 사용하면 성능 저하를 기대할 수 있습니다.(이 때문에 문제가 있는 답변)
한편, 로그인 루트는 세션 중에1번밖에 호출되지 않습니다.
따라서 일반적인 (세션 기반) 구현은 다음과 같습니다.
- /login 경로로 DB에서 데이터를 가져와 세션에서 캐시합니다.
- user_loader의 캐시에서 사용자를 로드합니다.
다음과 같은 경우:
@app.route("/login")
def login_callback():
user_data=my_fetch_from_db_based_on_whatever()
if my_check_credentials_ok(user_data)
session["user"]=user_data
login_user(User(user_data))
else:
abort(400)
:
@login_manager.user_loader
def load_user(user_id):
user_data = session["user"]
user=User(user_data)
return user if user.userid==user_id else None
언급URL : https://stackoverflow.com/questions/12075535/flask-login-cant-understand-how-it-works
'source' 카테고리의 다른 글
camel Case 변환Text to Title 대문자 텍스트 (0) | 2022.11.26 |
---|---|
PHP의 ==는 대소문자를 구분하는 문자열 비교입니까? (0) | 2022.11.26 |
스프링 MVC 유형 변환: PropertyEditor 또는 Converter? (0) | 2022.11.26 |
판다 데이터 프레임의 인덱스를 열로 변환하는 방법 (0) | 2022.11.26 |
웹 팩에서 jQuery 플러그인 종속성 관리 (0) | 2022.11.26 |