2022年6月10日 星期五

[研究]單一或多個 Email 格式驗證 (使用ASP.NET和 C#)

[研究]單一或多個 Email 格式驗證 (使用ASP.NET和 C#)

2022-06-10

續這篇,前端的檢查,對於駭客是可以用Burp Suite或其他工具或手法繞過,所以不管前端是否檢查,若要檢查,伺服器端的檢查是必須的。

[研究]單一或多個 Email 格式驗證 (使用 HTML5)
https://shaurong.blogspot.com/2022/06/email-html5.html

環境:Visual Studio 2022 + ASP.NET + WebForm + Web Application + C#

********************************************************************************

前端驗證 (瀏覽器端驗證)

參考這篇,可用 RegularExpressionValidator 於前端驗證
https://docs.microsoft.com/zh-tw/aspnet/web-forms/overview/older-versions-security/roles/role-based-authorization-cs

Default.aspx 中部份內容

<asp:TextBox runat="server" ID="Email" Text='<%# Bind("Email") %>'></asp:TextBox>    

<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"    
     ControlToValidate="Email" Display="Dynamic"    
     ErrorMessage="You must provide an email address." 
     SetFocusOnError="True">*</asp:RequiredFieldValidator>    

<asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server"    
     ControlToValidate="Email" Display="Dynamic" ForeColor="Red"   
     ErrorMessage="Email Address 格式錯誤,請修正。"    
     SetFocusOnError="True"    
     ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*">*
</asp:RegularExpressionValidator>    


********************************************************************************

伺服器端驗證方法 (後端驗證)

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" 
    CodeBehind="Default.aspx.cs" Inherits="WebApplication3.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        Single Email:<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox><br />
        <asp:Button ID="Button1" runat="server" Text="Send" OnClick="Button1_Click" /><br />
        <asp:Label ID="Label1" runat="server"></asp:Label><br />
        <br />
        Multiple Email:<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox><br />
        <asp:Button ID="Button2" runat="server" Text="Send" OnClick="Button2_Click" /><br />
        <asp:Label ID="Label2" runat="server"></asp:Label><br />
    </form>
</body>
</html>

Default.aspx.cs

using System;

namespace WebApplication3
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            bool isValidEmail = Common.IsValidEmail(TextBox1.Text);
            if  (isValidEmail == true)
                Label1.Text = "Email 格式驗證通過。";
            else
                Label1.Text = "Email 格式驗證失敗。";
        }
        protected void Button2_Click(object sender, EventArgs e)
        {
            bool isValidEmailList = Common.IsValidEmailList(TextBox2.Text);
            if (isValidEmailList == true)
                Label2.Text = "Email List 格式驗證通過。";
            else
                Label2.Text = "Email List 格式驗證失敗。";
        }
    }
}

Common.cs


using System;
using System.Globalization;
using System.Text.RegularExpressions;

namespace WebApplication3
{
    public class Common
    {
        // 如何:確認字串是否為有效的電子郵件格式 (C#)
        // https://msdn.microsoft.com/zh-tw/library/01escwtf(v=vs.110).aspx
        // https://docs.microsoft.com/zh-tw/dotnet/standard/base-types/how-to-verify-that-strings-are-in-valid-email-format

        // How to: Verify That Strings Are in Valid E-Mail Format | Microsoft Docs (VB)
        // https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/01escwtf(v=vs.100)

        // How to verify that strings are in valid email format | Microsoft Docs (C#)
// https://docs.microsoft.com/en-us/dotnet/standard/base-types/how-to-verify-that-strings-are-in-valid-email-format // RFC 2822的完整正則表達式(a full regex against RFC 2822 ) // https://code.iamcal.com/php/rfc822/full_regexp.txt // 當前的電子郵件正則表達式超過 23k,變得相當大。 // 這不包括巢狀註解剝離,它還要額外1k,也不含IPv4和IPv6規則,也額外還要1k。 // RFC 2822 - Internet Message Format // http://www.faqs.org/rfcs/rfc2822.html // End-to-end Email Address Verification for Applications - CodeProject // https://www.codeproject.com/Articles/5189/End-to-end-Email-Address-Verification-for-Applicat // 驗證 Email Address 格式,以及是否存在 ( 用 SMTP, DNS ) // 驗證字串是否符合單一 Email 格式 (微軟官方範例) public static bool IsValidEmail(string email) { if (string.IsNullOrWhiteSpace(email)) return false; try { // Normalize the domain email = Regex.Replace(email, @"(@)(.+)$", DomainMapper, RegexOptions.None, TimeSpan.FromMilliseconds(200)); // Examines the domain part of the email and normalizes it. string DomainMapper(Match match) { // Use IdnMapping class to convert Unicode domain names. var idn = new IdnMapping(); // Pull out and process domain name (throws ArgumentException on invalid) string domainName = idn.GetAscii(match.Groups[2].Value); return match.Groups[1].Value + domainName; } } catch (RegexMatchTimeoutException e) { return false; } catch (ArgumentException e) { return false; } try { return Regex.IsMatch(email, @"^[^@\s]+@[^@\s]+\.[^@\s]+$", RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250)); } catch (RegexMatchTimeoutException) { return false; } } // 驗證字串是否符合多個 Email 格式 (接受 , 和 ; 分隔) public static bool IsValidEmailList(string emailList) { bool isMatchEmail; emailList = emailList.Replace(" ", ""); // 移除半形空白 emailList = emailList.Replace(" ", ""); // 移除全形空白 if (!string.IsNullOrEmpty(emailList)) { foreach (var email in emailList.Split(',', ';')) { if (email.Length > 0) // Split 可能有些分段沒有內容 { // 只要其中一個 Email 為無效的電子郵件格式,就是無效 isMatchEmail = IsValidEmail(email); if (isMatchEmail == false) { return false; } } } } return true; } } }

實際測試




(完)

沒有留言:

張貼留言