2012-11-15 35 views
2

我需要连接到网站的管理面板(Joomla 2.5)。我的问题与这个topic非常相似,但我还没有找到解决方案,所以我正在寻找你的帮助。c#应用程序登录joomla

这里是我的示例代码:

WebClient Client = new WebClient(); 
System.Collections.Specialized.NameValueCollection Collection = 
new System.Collections.Specialized.NameValueCollection(); 
Collection.Add("username", "--my username--"); 
Collection.Add("passwd", "--my password--"); 
Collection.Add("option", "com_login"); 
Collection.Add("lang", ""); 
Collection.Add("task", "login"); 
//I find the token 
byte[] res = Client.UploadValues("http://mysite/administrator/index.php", "POST",  Collection); 
string source = Encoding.UTF8.GetString(res, 0, res.Length); 
Regex regex = new Regex("([a-zA-z0-9]{32})") 
Match match = regex.Match(source); 
if (match.Success) 
    string token = match.Value; 
//add token value to collection (example value 3e2aedd3de46f8a55ec15a6eb58e1c19) 
Collection.Add(token, "1"); 
//run authorization 
byte[] res = Client.UploadValues("http://mysite/administrator/index.php", "POST", Collection); 
string source = Encoding.UTF8.GetString(res, 0, res.Length); 
//in the row, the other token (example 06f1740ef6d6e87ae004500edddd7d7d) 

但它不工作。 “源”中的标记值不等于“标记”的值。我究竟做错了什么?

+0

这是HTTP流量,因此您可以使用WireShark轻松检查发布的数据和答案。 (对于HTTPS,我会推荐Fiddler。) – kol

+0

@FetFrumos,首先解决这个正则表达式regex = new Regex(“([a-zA-z0-9] {32})”),[a-zA-z0-9 ] {32} - > [a-zA-Z0-9] {32}。 –

+0

正则表达式更正 - [a-zA-Z0-9] {32}。但仍然不起作用:(。第一个值标记(示例) - 866b74901da31b30b782487d83bb09e4,最后一个值-9dfa5a59fa5fe8cf5e65bfcffbc7ee66。它不仅仅是字符,它们完全不同 – FetFrumos

回答

1

WebClient不是您尝试模仿网站行为时的最佳方式。改为使用HttpWebRequest和HttpWebResponse。并将请求的Connection属性设置为“Keep-alive”。

1

JérémieBertrand谢谢你的提示。我发现这个thread

随着WebResponse的不理解和使用

public class CookieAwareWebClient : WebClient 
{ 
private CookieContainer cookie = new CookieContainer(); 

protected override WebRequest GetWebRequest(Uri address) 
{ 
    WebRequest request = base.GetWebRequest(address); 
    if (request is HttpWebRequest) 
    { 
     (request as HttpWebRequest).CookieContainer = cookie; 
    } 
    return request; 
} 
} 

我写的代码如下

CookieAwareWebClient Client = new CookieAwareWebClient(); 
//...on the same 

它的工作原理:)类!

1

给大家,对于当前的Joomla 2.5版本的完整解决方案:

你所需要的,如上面提到的,这个扩展的Web客户端级:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net; 
using System.Text; 
using System.Threading.Tasks; 

namespace joomla.Util 
{ 
    public class CookieAwareWebClient : WebClient 
    { 
     private CookieContainer cookie = new CookieContainer(); 

     protected override WebRequest GetWebRequest(Uri address) 
     { 
      WebRequest request = base.GetWebRequest(address); 
      if (request is HttpWebRequest) 
       (request as HttpWebRequest).CookieContainer = cookie; 

      return request; 
     } 
    } 
} 

此外,你需要这个为Joomla登录:

public class JoomlaUserManagement 
{ 
    private const string _USERCOM = "com_users"; 
    private const string _LOGINVIEW = "login"; 
    private const string _LOGINTASK = "user.login"; 
    private const string _REGEXTOKEN = "([a-zA-Z0-9]{32})"; 
    private const string _REGEXRETURN = "([a-zA-Z0-9]{27}=)"; 
    private const string _REGEXRETURNLOGOUT = "([a-zA-Z0-9]{52})"; 

    /// <summary> 
    /// Gets the user name which is used to do the joomla login 
    /// </summary> 
    public String UserName { get; private set; } 

    /// <summary> 
    /// Gets the root uri to the joomla site. 
    /// </summary> 
    public Uri SiteRootUri { get; set; } 

    /// <summary> 
    /// Gets the last error occured when logging in 
    /// </summary> 
    public String LastError { get; private set; } 

    private String _password { get; set; } 

    private CookieAwareWebClient client; 

    /// <summary> 
    /// Initializes an instance for handling login or logoff 
    /// </summary> 
    /// <param name="userName">The username which is used to do the joomla login</param> 
    /// <param name="password">The username which is used to do the joomla login</param> 
    /// <param name="siteRoot">The root uri to the joomla site</param> 
    public JoomlaUserManagement(String userName, String password, Uri siteRoot) 
    { 
     UserName = userName; 
     _password = password; 
     SiteRootUri = siteRoot; 
     client = new CookieAwareWebClient(); 
    } 

    /// <summary> 
    /// Performs a joomla login. 
    /// </summary> 
    /// <returns>Returns true if succeeded. False if failed. If false, error will be written to <see cref="LastError"/></returns> 
    public Boolean Login() 
    {    
     NameValueCollection collection = new NameValueCollection(); 

     collection.Add("username", UserName); 
     collection.Add("password", _password); 
     collection.Add("option", _USERCOM); 
     collection.Add("lang", ""); 
     collection.Add("view", _LOGINVIEW); 

     // Request tokens. 
     String token = null; 
     String returnToken = null; 

     byte[] result = client.UploadValues(SiteRootUri, "POST", collection); 
     string resultingSource = Encoding.UTF8.GetString(result, 0, result.Length); 

     Regex regex = new Regex(_REGEXTOKEN); 
     Match match = regex.Match(resultingSource);    
     if (match.Success)    
      token = match.Value; 

     regex = new Regex(_REGEXRETURN); 
     match = regex.Match(resultingSource); 
     if (match.Success) 
      returnToken = match.Value; 

     // Perform login 
     if (returnToken != null && token != null) 
     { 
      collection.Add(token, "1"); 
      collection.Add("return", returnToken); 
      collection.Add("task", "user.login"); 

      result = client.UploadValues(SiteRootUri, "POST", collection); 
      resultingSource = Encoding.UTF8.GetString(result, 0, result.Length); 

      // Invalid token? 
      if (resultingSource.Length > 16) 
       return true; 
      else 
      { 
       LastError = "Unable to login."; 
       return false; 
      } 
     } 
     else 
     { 
      // We don't have all tokens 
      LastError = "Unable to retrieve tokens."; 
      return false; 
     } 
    } 

    public Boolean Logout() 
    {    
     NameValueCollection collection = new NameValueCollection(); 

     collection.Add("username", UserName); 
     collection.Add("password", _password); 
     collection.Add("option", _USERCOM); 
     collection.Add("lang", ""); 
     collection.Add("view", _LOGINVIEW); 

     // Request tokens. 
     String token = null; 
     String returnToken = null; 

     byte[] result = client.UploadValues(SiteRootUri, "POST", collection); 
     string resultingSource = Encoding.UTF8.GetString(result, 0, result.Length); 

     Regex regex = new Regex(_REGEXTOKEN); 
     Match match = regex.Match(resultingSource); 
     if (match.Success) 
      token = match.Value; 

     regex = new Regex(_REGEXRETURNLOGOUT); 
     match = regex.Match(resultingSource); 
     if (match.Success) 
      returnToken = match.Value; 

     // Perform login 
     if (returnToken != null && token != null) 
     { 
      collection.Add(token, "1"); 
      collection.Add("return", returnToken); 
      collection.Add("task", "user.logout"); 

      result = client.UploadValues(SiteRootUri, "POST", collection); 
      resultingSource = Encoding.UTF8.GetString(result, 0, result.Length); 

      // Invalid token? 
      if (resultingSource.Length > 16) 
       return true; 
      else 
      { 
       LastError = "Unable to logout."; 
       return false; 
      } 
     } 
     else 
     { 
      // We don't have all tokens 
      LastError = "Unable to retrieve tokens."; 
      return false; 
     } 
    } 
} 

然后,您可以登录或注销:

JoomlaUserManagement userMan = new JoomlaUserManagement("john.doe", "password", new Uri("http://www.customer.ltd")); 
Boolean loginResult = userMan.Login(); 
Boolean logoutResult = userMan.Logout(); 
+0

使用它的优点是什么,而不是在服务器上使用自定义PHP脚本,并发送一个http请求给它?(我当前发送我的用户名和密码到joomla网站,然后它发回,如果它“通过”和会话ID) – Cyral

+0

的好处是,它比写作更容易,更舒适一个自定义脚本;) –