使用C#登录https网站

5
我正在尝试编写一个小程序,以登录Verizon网站并检查本月剩余的通话分钟数。我需要帮助解决如何使用C#登录该网站的问题。我知道我需要使用Web请求来发布登录信息,但我不确定如何做到这一点。登录表单所在的网站是https://login.verizonwireless.com/amserver/UI/Login,但我不确定必须发布哪些信息才能登录以及如何实现它。下面是我在网站源代码中找到的内容。如果有人可以帮助我从C#程序中登录,我将非常感激。谢谢您的任何帮助。

表单方法="post"自动完成="off" 操作="https://login.verizonwireless.com:443/amserver/UI/Login"名称="loginForm" id="loginForm" onsubmit="return disableBut();">
输入类型="隐藏"名称="realm"值="vzw" />
输入类型="隐藏"名称="goto"值="" />
输入类型="隐藏"名称="gotoOnFail"值="" />
输入类型="隐藏"名称="gx_charset"值="UTF-8" />
输入类型="隐藏"名称="rememberUserNameCheckBoxExists"值="Y" />
h2样式="padding-left:0px;">登录我的Verizon
div class="clear10"> /div>


我可以推荐使用 Fiddler 或 Firebug 来拦截浏览器发送的 POST 请求。在那里,您可以看到发送到 Verizon 登录页面的确切内容。请在获取此信息后更新您的问题。 - Pauli Østerø
2个回答

2
首先,您缺少两个重要的字段 :) 如果您查看HTML,表单中有两个附加字段 - IDToken1(用户名)和IDToken2(密码)。
如果您在POST请求中提供这些字段,则应该会收到一些Cookie,您可以在随后的请求中使用它们。这些将标识您为已登录用户。
当然,由于我没有有效的登录,因此无法完全测试此功能,但这是一个开头:
class VerizonLogin
{
    CookieContainer Cookies = new CookieContainer();

    void Main()
    {
        Login("test","testpass");

        // Now the cookies in "Cookies" are all set.
        // Ensure you set CookieContainer on all subsequent requests
    }

    void Login(string username, string password)
    {
        var wr = (HttpWebRequest)WebRequest.Create("https://login.verizonwireless.com:443/amserver/UI/Login");
        wr.Method = "POST";
        wr.ContentType = "application/x-www-form-urlencoded";
        wr.Referer = "https://login.verizonwireless.com/amserver/UI/Login"; // my tests show this is needed
        wr.CookieContainer = Cookies;

        var parameters = new Dictionary<string,string>{
            {"realm", "vzw"},
            {"goto",""},
            {"gotoOnFail",""},
            {"gx_charset", "UTF-8"},
            {"rememberUserNameCheckBoxExists","Y"},
            {"IDToken1", username},
            {"IDToken2", password}
        };

        using (var requestStream = wr.GetRequestStream())
        using (var writer = new StreamWriter(requestStream,Encoding.UTF8))
            writer.Write(ParamsToFormEncoded(parameters));

        using (var response = (HttpWebResponse)wr.GetResponse())
        {
            // here you need to detect a correct login... this might be one of the cookies.
            // if incorrect throw an exception or something.
        }
    }

    string ParamsToFormEncoded(Dictionary<string,string> parameters)
    {
        return string.Join("&", parameters.Select(kvp => 
            Uri.EscapeDataString(kvp.Key).Replace("%20","+") + "=" + Uri.EscapeDataString(kvp.Value).Replace("%20","+")
        ).ToArray());
    }
}

感谢大家的回复。Porges,我尝试了你的建议,它非常有效。非常感谢你的帮助。再次感谢。 - Baller2004
谢谢,今天对我很有帮助。 - mlusiak

1

这里有两个函数可以帮助你完成这个任务。是的,你说得对,你必须使用webrequest,但是你需要伪造一个回调来验证https证书。你应该能够直接使用这些函数。

C#

private bool ValidateCert(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
    return true;
}

private string PostToSite(string url)
{
    string result = string.empty;

    byte[] postBuffer = System.Text.Encoding.GetEncoding(1252).GetBytes("realm=vzw&goto=&gotoOnFail=&gx_charset=UTF-8&rememberUserNameCheckBoxExists=Y");

    HttpWebRequest webRequest = (HttpWebRequest)Net.WebRequest.Create(_endpoint);
    webRequest.KeepAlive = false;
    webRequest.AllowAutoRedirect = false;

    ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(ValidateCert);

    webRequest.ContentLength = postBuffer.Length;
    webRequest.Method = "POST";
    webRequest.ContentType = "application/x-www-form-urlencoded";

    using (Stream str = webRequest.GetRequestStream()) {
        str.Write(postBuffer, 0, postBuffer.Length);
    }

    using (System.Net.HttpWebResponse res = (HttpWebResponse)webRequest.GetResponse()) {
        using (StreamReader sr = new StreamReader(res.GetResponseStream())) {
            result = sr.ReadToEnd();
        }
    }

    return result;
}

VB.NET

Private Function ValidateCert(ByVal sender As Object, ByVal certificate As System.Security.Cryptography.X509Certificates.X509Certificate, ByVal chain As System.Security.Cryptography.X509Certificates.X509Chain, ByVal sslPolicyErrors As System.Net.Security.SslPolicyErrors) As Boolean
 Return True
End Function

Private Function PostToSite(url as string) as string
    Dim result as string = string.empty

    Dim postBuffer As Byte() = System.Text.Encoding.GetEncoding(1252).GetBytes("realm=vzw&goto=&gotoOnFail=&gx_charset=UTF-8&rememberUserNameCheckBoxExists=Y")

    Dim webRequest As HttpWebRequest = CType(Net.WebRequest.Create(_endpoint), HttpWebRequest)
    webRequest.KeepAlive = False
    webRequest.AllowAutoRedirect = False

    ServicePointManager.ServerCertificateValidationCallback = New System.Net.Security.RemoteCertificateValidationCallback(AddressOf ValidateCert)

    webRequest.ContentLength = postBuffer.Length
    webRequest.Method = "POST"
    webRequest.ContentType = "application/x-www-form-urlencoded"

    Using str As Stream = webRequest.GetRequestStream()
        str.Write(postBuffer, 0, postBuffer.Length)
    End Using

    Using res As System.Net.HttpWebResponse = CType(webRequest.GetResponse(), HttpWebResponse)
        Using sr As New StreamReader(res.GetResponseStream())
            result = sr.ReadToEnd()
        End Using
    End Using

    return result
End Function

这不是他们遇到的问题。此外,您应该仅在开发环境中执行此操作,对于生产来说这不是一个好主意。 - porges

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接