我有一个 quart web 应用程序,它连接到 LDAP 服务器进行登录。
我想实施 2FA,越容易越好,因为客户不愿意使用手机扫描条码登录。
我怎么能做到这一点?
@app.route('/login', methods=['GET', 'POST'])
async def login():
session.permanent = True
app.permanent_session_lifetime = timedelta(minutes=240)
global pass_errnum
if current_user.is_authenticated:
return redirect(url_for('index'))
# if not using wtf_form, can try below from Quart Tutorials
# username = (await request.form)['username']
# password = (await request.form)['password']
form = LoginForm()
if form.validate_on_submit():
if pass_errnum > 5:
error = "Five failed login attempts, account locked"
return await render_template('login.html', title='Sign In', form=form, error=error)
user = AuthUser.query.filter_by(username=form.username.data).first()
# get Client IP Address
# cannot use request.environ because this is not WSGI
if 'X-Forwarded-For' in request.headers:
client_ip = request.headers['X-Forwarded-For']
else:
client_ip = request.remote_addr
if user is None:
# return redirect(url_for('login'))
error = "Wrong Login Information"
add_log(ip_address=client_ip, actor=form.username.data, action='LOGIN', item_type='AuthUser',
item_id=form.username.data, activity=form.password.data, result='FAIL')
pass_errnum +=1
return await render_template('login.html', title='Sign In', form=form, error=error)
else:
if user.auth_source == 'LDAP': # authenticate via ldap
headers = {'Authorization': get_ldap_auth_key()}
body = {"username": form.username.data, "password": form.password.data}
response = requests.post(url=app.config['LDAP_URL'], json=body, headers=headers)
result = response.json()
logger.info(result)
if result['code'] != "OK":
error = "Wrong Login Information"
add_log(ip_address=client_ip, actor=form.username.data, action='LOGIN', item_type='AuthUser',
item_id=form.username.data, activity=form.password.data, result='FAIL')
pass_errnum += 1
return await render_template('login.html', title='Sign In', form=form, error=error)
elif not user.check_password(form.password.data):
error = "Wrong Login Information"
add_log(ip_address=client_ip, actor=form.username.data, action='LOGIN', item_type='AuthUser',
item_id=form.username.data, activity=form.password.data, result='FAIL')
pass_errnum += 1
return await render_template('login.html', title='Sign In', form=form, error=error)
login_user(user, remember=form.remember_me.data)
next_page = request.args.get('next')
if not next_page or url_parse(next_page).netloc != '':
next_page = url_for('course_index')
add_log(ip_address=client_ip, actor=form.username.data, action='LOGIN', item_type='AuthUser',
item_id=form.username.data, result='SUCCESS')
pass_errnum = 0
return redirect(next_page)
return await render_template('login.html', title='Sign In', form=form)
最好不要使用任何与条形码扫描相关的方法,因为我的客户不愿意这样做。