You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 02:45:35