首先我们需要明确双因素验证的概念和作用。双因素验证(Two-Factor Authentication,2FA)是指验证用户身份的时候,除了要求用户提供用户名和密码之外,还需要第二个认证因素,例如卡片、手机、指纹等。
在Python中实现2FA需要使用第三方模块OTP(One-Time Password),它提供了基于HOTP(HMAC-based One-Time Password)和TOTP(Time-based One-Time Password)的实现。
下面是实现2FA的完整攻略:
第一步:安装OTP模块
使用pip命令安装OTP模块:
pip install pyotp
第二步:生成2FA密钥
使用OTP模块生成2FA密钥,该密钥将用于生成认证码。可以使用HOTP或TOTP算法生成2FA密钥,这里我们选用Totp算法来生成2FA密钥,示例如下:
import pyotp
totp = pyotp.TOTP('JBSWY3DPEHPK3PXP')
print(totp.now())
运行以上代码,输出的totp.now()即为生成的2FA密钥。
第三步:生成6位认证码
使用TOTP算法和2FA密钥,每次生成一个6位数的认证码,该认证码在30秒内有效。示例如下:
import pyotp
totp = pyotp.TOTP('JBSWY3DPEHPK3PXP')
# 获取当前时间戳
current_time = int(time.time())
# 获取时间戳对应的认证码
auth_code = totp.at(current_time)
print(auth_code)
以上代码中,totp.at(current_time)
方法返回的auth_code就是当前6位认证码。
示例说明1:使用Flask实现2FA登录
在此示例中,我们将使用Flask框架,实现一个简单的2FA登录功能。该示例中,我们将使用session会话存储获取的2FA密钥以及用户账户和密码,并在每次登录时,进行2FA认证。
首先是Flask路由的实现代码:
from flask import Flask, request, render_template, session
import pyotp
app = Flask(__name__)
app.secret_key = '123456'
@app.route('/', methods=['GET', 'POST'])
def login2fa():
if request.method == 'POST':
# 获取用户账户和密码
username = request.form['username']
password = request.form['password']
# 获取2FA密钥
totp = pyotp.TOTP(session['2fa_key'])
# 验证账户和密码
if username == 'admin' and password == '123456':
# 获取当前时间戳
current_time = int(time.time())
auth_code = request.form['auth_code']
# 验证认证码
if totp.verify(auth_code, current_time):
return 'login success'
else:
return 'login failed'
else:
return 'login failed'
else:
# 生成2FA密钥
totp = pyotp.TOTP(pyotp.random_base32())
session['2fa_key'] = totp.secret
return render_template('login2fa.html')
在上述代码中,session['2fa_key']
用于存储生成的2FA密钥,pyotp.TOTP(session['2fa_key'])
用于获取2FA密钥,totp.verify(auth_code, current_time)
用于验证认证码。需要注意的是,pyotp.random_base32()
方法用于生成32位的随机密钥,建议使用该方法生成2FA密钥。
然后是Flask模板的实现代码,即login2fa.html文件:
<!DOCTYPE html>
<html>
<head>
<title>2FA login</title>
</head>
<body>
<form action="/" method="post">
<label>username:</label><input type="text" name="username"><br>
<label>password:</label><input type="password" name="password"><br>
<label>auth code:</label><input type="text" name="auth_code"><br>
<input type="submit" value="login">
</form>
</body>
</html>
运行Flask应用程序,即可通过http://localhost:5000/
进入2FA登录页面。
示例说明2:使用Django实现2FA登录
在此示例中,我们将使用Django框架,实现一个简单的2FA登录功能。该示例中,我们将使用session会话存储获取的2FA密钥以及用户账户和密码,并在每次登录时,进行2FA认证。
首先是Django视图函数的实现代码:
from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth import authenticate, login, logout
import pyotp
def login_view(request):
if request.method == 'POST':
# 获取用户账户和密码
username = request.POST['username']
password = request.POST['password']
# 获取2FA密钥
totp = pyotp.TOTP(request.session['2fa_key'])
# 验证账户和密码
user = authenticate(request, username=username, password=password)
if user is not None:
# 获取当前时间戳
current_time = int(time.time())
auth_code = request.POST['auth_code']
# 验证认证码
if totp.verify(auth_code, current_time):
login(request, user)
messages.success(request, 'login success')
return redirect('home')
else:
messages.error(request, 'Invalid auth code')
else:
messages.error(request, 'Invalid username or password')
# 生成2FA密钥
totp = pyotp.TOTP(pyotp.random_base32())
request.session['2fa_key'] = totp.secret
return render(request, 'login.html')
在上述代码中,request.session['2fa_key']
用于存储生成的2FA密钥,pyotp.TOTP(request.session['2fa_key'])
用于获取2FA密钥,totp.verify(auth_code, current_time)
用于验证认证码。需要注意的是,pyotp.random_base32()
方法用于生成32位的随机密钥,建议使用该方法生成2FA密钥。
然后是Django模板的实现代码,即login2fa.html文件:
{% extends 'base.html' %}
{% block content %}
<form method="post">
{% csrf_token %}
<label>username:</label><input type="text" name="username"><br>
<label>password:</label><input type="password" name="password"><br>
<label>auth code:</label><input type="text" name="auth_code"><br>
<input type="submit" value="login">
</form>
{% endblock %}
运行Django应用程序,即可通过http://localhost:8000/login/
进入2FA登录页面。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python实现双因素验证2FA的示例代码 - Python技术站