通过C#登录网站

7

我已经尝试了网上所有关于如何实现登录此网站的方法。以下是最近的失败记录。

 // I have tried with multiple different URLS this one 
 // and http://www.movable.com/login do not throw errors
 string url = "http://portal.movable.com/";
 string username = "<myusername>";
 string password = "<mypassword>";
 string authTok = @"+HOt3NTkkIAHkMSMvzQisEquhun9xvIG1mHzIEh6CAo=";
 string postData = "utf8=✓" + "&authenticity_token=" + authTok +
      "&user[login]=" + username + 
      "&user[password]=" + password + "&user[offset]=-5";

var container = new CookieContainer();
var buffer = Encoding.UTF8.GetBytes(postData);

var request = (HttpWebRequest)HttpWebRequest.Create(url);
request.CookieContainer = container;
request.UserAgent = "Mozilla/5.0";
request.Method = "POST";
request.KeepAlive = true;
request.AllowAutoRedirect = true;
request.CookieContainer = container;
request.ContentLength = buffer.Length;
request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";

using (var requestStream = request.GetRequestStream())
    requestStream.Write(buffer, 0, buffer.Length);

using (var response = request.GetResponse())
{

        using (var reader = new StreamReader(response.GetResponseStream()))
        {
            var result = reader.ReadToEnd();
            //this is to read the page source after the request
            MessageBox.Show(result); 
        }             
}

以下是该网站的相关数据(我知道示例中令牌不同,但我已将它们设置为相同,仍无法正常工作)

<form accept-charset="UTF-8" action="/signin" class="new_user" id="new_user" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="hHfoUnIbi+6RB51x1cqXqAYHkjz9mCi7nc86gMdiMOo=" /></div>

    <p class="notice">Signed out successfully.</p>

  <h2>login to your account</h2>

  <label for="user_login">Login</label>
  <input id="user_login" name="user[login]" size="30" type="text" />
  <label for="user_password">Password</label>
  <input id="user_password" name="user[password]" size="30" type="password" />

  <input id="user_offset" name="user[offset]" type="hidden" />


  <label for="user_remember_me">
    <input name="user[remember_me]" type="hidden" value="0" /><input id="user_remember_me" name="user[remember_me]" type="checkbox" value="1" /> 
    Remember me on this computer.
  </label>
  <button class="login" name="button" type="submit">Login</button>
    <a href="/users/password/new" class="forgotPassword">Forgot password?</a>
  </form>  </div>

示例HTML表单显示该表单被发布到/signin。请尝试将您的URL更改为http://portal.movable.com/signin。 - Rich
我已经尝试过这个,但它抛出了一个错误。 - DotNetRussell
实际上,以前它会抛出一个错误,现在它只是像其他所有页面一样将我返回到登录页面。 - DotNetRussell
此外,authenticity_token可以在每个页面上动态生成,以防止跨站点伪造。如果是这种情况,除非您首先请求登录页面,然后提取令牌进行后续的登录尝试,否则您将没有有效的令牌。 - Rich
这也是我考虑过的事情。最初我构建它是为了首先获取授权令牌,直到我意识到它只有在大约30分钟后才会更改。 - DotNetRussell
1个回答

13
试试这种方式:
        var cookieJar = new CookieContainer();
        CookieAwareWebClient client = new CookieAwareWebClient(cookieJar);

        // the website sets some cookie that is needed for login, and as well the 'authenticity_token' is always different
        string response = client.DownloadString("http://portal.movable.com/signin");

        // parse the 'authenticity_token' and cookie is auto handled by the cookieContainer
        string token = Regex.Match(response, "authenticity_token.+?value=\"(.+?)\"").Groups[1].Value;
        string postData =
            string.Format("utf8=%E2%9C%93&authenticity_token={0}&user%5Blogin%5D=USERNAME&user%5Bpassword%5D=PASSWORD&user%5Boffset%5D=5.5&user%5Bremember_me%5D=0&button=", token);


        //WebClient.UploadValues is equivalent of Http url-encode type post
        client.Method = "POST";
        response = client.UploadString("http://portal.movable.com/signin", postData);


        //i am getting invalid user/pass, but i am sure it will work fine with normal user/password

    }

额外使用的类:

public class CookieAwareWebClient : WebClient
{
    public string Method;
    public CookieContainer CookieContainer { get; set; }
    public Uri Uri { get; set; }

    public CookieAwareWebClient()
        : this(new CookieContainer())
    {
    }

    public CookieAwareWebClient(CookieContainer cookies)
    {
        this.CookieContainer = cookies;
    }

    protected override WebRequest GetWebRequest(Uri address)
    {
        WebRequest request = base.GetWebRequest(address);
        if (request is HttpWebRequest)
        {
            (request as HttpWebRequest).CookieContainer = this.CookieContainer;
            (request as HttpWebRequest).ServicePoint.Expect100Continue = false;
            (request as HttpWebRequest).UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0";
            (request as HttpWebRequest).Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
            (request as HttpWebRequest).Headers.Add(HttpRequestHeader.AcceptLanguage, "en-US,en;q=0.5");
            (request as HttpWebRequest).Referer = "http://portal.movable.com/signin";
            (request as HttpWebRequest).KeepAlive = true;
            (request as HttpWebRequest).AutomaticDecompression = DecompressionMethods.Deflate |
                                                                 DecompressionMethods.GZip;
            if (Method == "POST")
            {
                (request as HttpWebRequest).ContentType = "application/x-www-form-urlencoded";
            }

        }
        HttpWebRequest httpRequest = (HttpWebRequest)request;
        httpRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
        return httpRequest;
    }

    protected override WebResponse GetWebResponse(WebRequest request)
    {
        WebResponse response = base.GetWebResponse(request);
        String setCookieHeader = response.Headers[HttpResponseHeader.SetCookie];

        if (setCookieHeader != null)
        {
            //do something if needed to parse out the cookie.
            try
            {
                if (setCookieHeader != null)
                {
                    Cookie cookie = new Cookie(); //create cookie
                    this.CookieContainer.Add(cookie);
                }
            }
            catch (Exception)
            {

            }
        }
        return response;

    }
}

收到响应

<!DOCTYPE html>
<html>
<head>
  <title>MOVband Portal</title>
  <link href="/assets/application-f9d3794ad4639d96cd50c115ad241438.css" media="all" rel="stylesheet" type="text/css" />
  <!--[if lt IE 9]>
    <script src="/assets/modernizr-9b693978fbc3fcd01874b01875a736bf.js" type="text/javascript"></script>
    <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
  <![endif]-->
  <!--[if IE 7]>
    <link href="/assets/ie7-ca67da697ba8da1de77889ceedc4db1a.css" media="all" rel="stylesheet" type="text/css" />
  <![endif]-->
  <script src="/assets/application-b1fcaae48e75e2455cf45e1d75983267.js" type="text/javascript"></script>
  <meta content="authenticity_token" name="csrf-param" />
<meta content="aC33zdBSSAz63dVjOgYXR/L6skV/QxxHe4XqX3UYCek=" name="csrf-token" />
</head>
<body id="login">
  <header>
    <div class="container">
      <a href="http://movable.com">
        <img alt="Movablelogo" class="logo" src="/assets/movableLogo-3429bb636ded1af0a80951c7d4386770.png" />
</a>    </div>
  </header>

  <section class="main">
    <div class="container">
      <div id="loginWindow" class="cf">
  <img alt="Movbandlogologin" class="movbandlogo" src="/assets/MOVbandLogologin-3cacbbe2b9bb05b16a3ca521acf81fc6.png" />
  <div class="cf">
    <div id="welcomeMessage">
      <h1>Welcome</h1>

      <img alt="Movbanddevice" class="device" src="/assets/MOVbandDevice-acbb62593330775ac09dced40e28e8e2.png" />
      <p>
        Just got your MOVband? We'll have you moving in no time with our quick product registration and setup.
        <a href="/join">Join &gt;</a>
      </p>
    </div>
    <form accept-charset="UTF-8" action="/signin" class="new_user" id="new_user" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="authenticity_token" type="hidden" value="aC33zdBSSAz63dVjOgYXR/L6skV/QxxHe4XqX3UYCek=" /></div>

        <p class="alert">Invalid email or password.</p>

      <h2>login to your account</h2>

      <label for="user_login">Login</label>
      <input id="user_login" name="user[login]" size="30" type="text" value="USERNAME" />
      <label for="user_password">Password</label>
      <input id="user_password" name="user[password]" size="30" type="password" />

      <input id="user_offset" name="user[offset]" type="hidden" value="5.5" />


      <label for="user_remember_me">
        <input name="user[remember_me]" type="hidden" value="0" /><input id="user_remember_me" name="user[remember_me]" type="checkbox" value="1" /> 
        Remember me on this computer.
</label>
      <button class="login" name="button" type="submit">Login</button>
        <a href="/users/password/new" class="forgotPassword">Forgot password?</a>
</form>  </div>
</div>

    </div>
  </section>

  <footer>
    <div class="container">
      <div class="social_icons">
        <a href="https://www.facebook.com/getMOVband" class="fb_link" target="_blank"></a>
        <a href="https://twitter.com/getmovband" class="tw_link" target="_blank"></a>
        <a href="http://www.youtube.com/getmovband" class="yt_link" target="_blank"></a>
        <a href="http://www.linkedin.com/company/2355960" class="li_link" target="_blank"></a>
      </div>
    </div>
  </footer>
</body>
</html>

是的!这个完美地运行了!你能否在三句话内指出我做错了什么? - DotNetRussell
1
// 网站设置了一些必须用于登录的 cookie,而且 'authenticity_token' 总是不同的,所以在发送 POST 请求之前,需要先发送 GET 请求来设置默认的 cookie! - Parimal Raj
1
Cookie: _WebClient_session=BAh7B0kiD3Nlc3Npb25faWQGOgZFRkkiJTc5MTdkYjkwMDAzNWZmMjRiNzJkYmUxNWJmMjk3NGNkBjsAVEkiEF9jc3JmX3Rva2VuBjsARkkiMWFDMzN6ZEJTU0F6NjNkVmpPZ1lYUi9MNnNrVi9ReHhIZTRYcVgzVVlDZWs9BjsARg%3D%3D--6f32e8ef689fd9d04157c29c7e47669aa8d08d0f 这个头在POST请求中丢失了! - Parimal Raj
太棒了,非常感谢。这个问题困扰我有一段时间了。如果我可以投两次赞,我一定会的。 - DotNetRussell
1
@AMR - 没关系!我已经做这项工作很长时间了,所以我总是检查这些事情! - Parimal Raj
你是如何找出postData格式应该是什么样子的呢? - DotNetRussell

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