如何在ASP.NET 4 WebForms中实现Google Authenticator?
在.NET 4 ASP.NET WebForm中实现Google Authenticator双因素认证
1. 安装依赖包
通过NuGet安装适配.NET 4的Google Authenticator包:
Install-Package GoogleAuthenticator
2. 核心工具类
创建静态工具类封装认证逻辑,方便页面调用:
using Google.Authenticator; public static class GoogleAuthHelper { // 生成用户唯一密钥(需存入数据库) public static string GenerateSecretKey() { var authenticator = new TwoFactorAuthenticator(); return authenticator.GenerateRandomKey(); } // 获取Google Authenticator可扫描的二维码URL // 参数:issuerName-应用名称;accountName-用户唯一标识(如邮箱/用户名);secretKey-生成的密钥 public static string GetQrCodeUrl(string issuerName, string accountName, string secretKey) { var authenticator = new TwoFactorAuthenticator(); var setupInfo = authenticator.GenerateSetupCode(issuerName, accountName, secretKey, false); return setupInfo.QrCodeSetupImageUrl; } // 验证用户输入的6位验证码 // 参数:secretKey-用户密钥;code-输入的验证码 public static bool ValidateCode(string secretKey, string code) { var authenticator = new TwoFactorAuthenticator(); // 允许前后1分钟时间偏移,兼容时钟误差 return authenticator.ValidateTwoFactorPIN(secretKey, code, TimeSpan.FromMinutes(1)); } }
3. 用户绑定流程(BindGoogleAuth.aspx)
后台代码(BindGoogleAuth.aspx.cs)
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { var userId = Session["UserId"]?.ToString(); if (string.IsNullOrEmpty(userId)) { Response.Redirect("Login.aspx"); return; } // 生成密钥 var secretKey = GoogleAuthHelper.GenerateSecretKey(); // 临时存Session,验证后再写入数据库 Session["TempGoogleAuthSecret"] = secretKey; // 生成二维码并显示 var qrCodeUrl = GoogleAuthHelper.GetQrCodeUrl("你的应用名称", userId, secretKey); imgQrCode.ImageUrl = qrCodeUrl; } } protected void btnVerify_Click(object sender, EventArgs e) { var secretKey = Session["TempGoogleAuthSecret"]?.ToString(); var inputCode = txtVerificationCode.Text.Trim(); if (string.IsNullOrEmpty(secretKey) || string.IsNullOrEmpty(inputCode)) { lblMessage.Text = "请输入验证码"; return; } if (GoogleAuthHelper.ValidateCode(secretKey, inputCode)) { lblMessage.Text = "绑定成功!"; // 将密钥写入用户数据库(替换为你的DB操作) // UserDb.UpdateGoogleAuthSecret(Session["UserId"].ToString(), secretKey); Session.Remove("TempGoogleAuthSecret"); } else { lblMessage.Text = "验证码无效,请重试"; } }
前台页面(BindGoogleAuth.aspx)
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="BindGoogleAuth.aspx.cs" Inherits="BindGoogleAuth" %> <!DOCTYPE html> <html> <head runat="server"> <title>绑定Google Authenticator</title> </head> <body> <form id="form1" runat="server"> <div> <h3>扫描二维码完成绑定</h3> <asp:Image ID="imgQrCode" runat="server" /> <br /> <asp:TextBox ID="txtVerificationCode" runat="server" Placeholder="输入Google Authenticator的6位验证码"></asp:TextBox> <asp:Button ID="btnVerify" runat="server" Text="验证绑定" OnClick="btnVerify_Click" /> <asp:Label ID="lblMessage" runat="server" ForeColor="Red"></asp:Label> </div> </form> </body> </html>
4. 登录验证流程(Login.aspx)
后台代码(Login.aspx.cs)
protected void btnLogin_Click(object sender, EventArgs e) { var username = txtUsername.Text.Trim(); var password = txtPassword.Text.Trim(); // 第一步:验证账号密码(替换为你的业务逻辑) var user = UserDb.GetUserByUsername(username); if (user == null || user.Password != password) // 实际项目必须用哈希密码验证 { lblMessage.Text = "账号或密码错误"; return; } // 第二步:检查用户是否开启双因素认证 if (!string.IsNullOrEmpty(user.GoogleAuthSecret)) { pnlTwoFactor.Visible = true; Session["PendingLoginUserId"] = user.Id; } else { // 直接登录成功 Session["UserId"] = user.Id; Response.Redirect("Default.aspx"); } } protected void btnVerifyTwoFactor_Click(object sender, EventArgs e) { var userId = Session["PendingLoginUserId"]?.ToString(); var inputCode = txtTwoFactorCode.Text.Trim(); if (string.IsNullOrEmpty(userId) || string.IsNullOrEmpty(inputCode)) { lblMessage.Text = "请输入验证码"; return; } var user = UserDb.GetUserById(userId); if (user == null) { lblMessage.Text = "用户不存在"; return; } if (GoogleAuthHelper.ValidateCode(user.GoogleAuthSecret, inputCode)) { // 双因素验证通过,完成登录 Session["UserId"] = user.Id; Session.Remove("PendingLoginUserId"); Response.Redirect("Default.aspx"); } else { lblMessage.Text = "验证码无效,请重试"; } }
前台页面(Login.aspx)
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Login.aspx.cs" Inherits="Login" %> <!DOCTYPE html> <html> <head runat="server"> <title>登录</title> </head> <body> <form id="form1" runat="server"> <div> <asp:TextBox ID="txtUsername" runat="server" Placeholder="用户名"></asp:TextBox> <br /> <asp:TextBox ID="txtPassword" runat="server" TextMode="Password" Placeholder="密码"></asp:TextBox> <br /> <asp:Button ID="btnLogin" runat="server" Text="登录" OnClick="btnLogin_Click" /> <br /> <asp:Panel ID="pnlTwoFactor" runat="server" Visible="false"> <asp:TextBox ID="txtTwoFactorCode" runat="server" Placeholder="输入Google Authenticator验证码"></asp:TextBox> <asp:Button ID="btnVerifyTwoFactor" runat="server" Text="验证" OnClick="btnVerifyTwoFactor_Click" /> </asp:Panel> <asp:Label ID="lblMessage" runat="server" ForeColor="Red"></asp:Label> </div> </form> </body> </html>
注意事项
- 用户密钥必须持久化存储到数据库,不能仅依赖Session
- 实际项目中密码必须用哈希算法(如SHA256)加密存储,禁止明文
- 可根据需求调整验证码时间偏移范围,默认1分钟适配大部分场景
内容的提问来源于stack exchange,提问作者alen george
相关产品推荐
相关产品推荐

