0

我到处寻找,我似乎无法弄清楚:

在 C# 中对 cPanel 会话进行身份验证后,我从 url 中抓取安全令牌并尝试将其插入 API 调用,我收到各种错误(通常访问被拒绝或无效令牌)。

需要注意的一件事是,我正在尝试使用 cPanel 中的安全端口,在本例中为端口 2083。但是,当使用 hostgator 托管时,我会从我的域重定向到安全的 hostgator 子域以登录(gatorXXXX .hostgator.com:2083/),我想知道这是否是在丢东西。

首先,我尝试使用以下代码,我在另一个 stackoverflow 帖子中找到了该代码,但我将其修改为:

检查 cPanel 登录是否将我从我的域重定向到子域进行登录,如果是,则抓取该子域,然后将其插入,再次运行代码,并获取会话令牌。

public static string Connect(string url, string userName, string password, string userAgent, string postData, int timeOut)
    {
        string result = "";

        // set a flag to determine if the cpanel page is different than the url
        bool moved = false;
        string newUrl = "";

        try
        {
            // Create a request for the URL.        
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

            if (userAgent == null)
                userAgent = UserAgent;

            request.UserAgent = userAgent;
            request.Timeout = timeOut;

            if (userName.Length > 0)
            {
                string authInfo = userName + ":" + password;
                authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
                request.Headers["Authorization"] = "Basic " + authInfo;
                request.AllowAutoRedirect = false;
            }

            if (postData.Length > 0)
            {
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
                request.CookieContainer = new CookieContainer();
                // Create POST data and convert it to a byte array.
                byte[] byteArray = Encoding.UTF8.GetBytes(postData);
                request.ContentLength = byteArray.Length;
                using (Stream dataStream = request.GetRequestStream())
                {
                    dataStream.Write(byteArray, 0, byteArray.Length);
                }
            }

            // Get the response.
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                // Get the stream containing content returned by the server.
                Stream dataStream = response.GetResponseStream();
                response.Cookies = new CookieCollection();
                // Open the stream using a StreamReader for easy access.
                using (StreamReader reader = new StreamReader(dataStream))
                {
                    result = string.Format("Server response:\n{0}\n{1}", response.StatusDescription, reader.ReadToEnd());
                }


                if (response.StatusDescription.ToLower().Contains("moved") && !response.Headers.ToString().Contains("/cpsess"))
                {
                    newUrl = StringUtils.ExtractNoCase(result.ToLower(), "url=", "\">", 1);
                    moved = true;
                }
                else return result;
            }
        }

        catch (Exception e)
        {
            result = string.Format("There was an error:\n{0}", e.Message);
        }

        // if the cpanel login is at a different location, Connect() with new url
        if (moved == true)
        {
            result = Connect(newUrl, userName, password, null, postData, 8000);
        }
        return result;
    }

现在获得安全令牌后,我尝试将其插入原始 url ( https://mydomain.com:2083/cpsess12334455/xml-api/.. ) 和 hostgator 子域 ( https:// gatorXXXX.hostgator.com:2083/cpsess/... .) 两种方式我都被拒绝了。

因此,在与该问题斗争了几天之后,我决定尝试 phalanger 来执行此任务,因为我发现的大多数 cPanel 身份验证示例都在 php/curl 中。

所以我使用以下代码:

function Authentication($hostname, $username, $password)
{
    $download_url = "https://".$hostname.":2083/login/";
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,0);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER,0);
    curl_setopt($curl, CURLOPT_HEADER,0);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER,1);
    curl_setopt($curl, CURLOPT_URL, $download_url);
    curl_setopt($curl, CURLOPT_POSTFIELDS, "user=".$username."&pass=".$password);
    $result = curl_exec($curl);
    curl_close($curl);
    $parts = explode( 'URL=', $result);
    $session_parts = explode( '/frontend/', $parts[1]);
    $token = $session_parts[0];

    $subdomain = "https://".$hostname.":2083" . $token . "/json-api/cpanel";

 }

然后尝试发布类似以下内容(应该将新的子域附加到域):

$curl = curl_init();
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,0);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER,0);
    curl_setopt($curl, CURLOPT_HEADER,0);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER,1);
    curl_setopt($curl, CURLOPT_URL, $subdomain);
    curl_setopt($curl, CURLOPT_POSTFIELDS, "user=username&cpanel_jsonapi_module=SubDomain&cpanel_jsonapi_func=addsubdomain&cpanel_jsonapi_version=2&domain=testingthis2&rootdomain=myrootdomain.com");

    $result = curl_exec($curl);
    curl_close($curl);

当我获得安全令牌时,我总是得到以下结果,即使在复制安全令牌并从浏览器运行 API 调用时也是如此:

{"cpanelresult":{"apiversion":"2","error":"Token denied","data":{"reason":"Token denied","re​​sult":"0"},"type": “文本”}}

所以我很难过。我宁愿在 c# 中完成这一切,而不是与 phalanger 混淆,因为我不像 C# 那样精通 PHP,但在这一点上,如果可行的话,我会采取任何一种方法。

我要做的就是获取安全令牌并将其插入我选择的 API 调用中,并让 cPanel 接受我的安全令牌并处理 API 调用。

4

1 回答 1

0

这可能更多的是建议而不是答案,因为我不知道 C# 和您的确切情况。

根据我的经验,我发现使用会话令牌是不够的,您还必须在与登录相同的会话中使用它(我认为存储在 cookie 中)。因此,例如,如果您在一个浏览器中登录但尝试使用会话令牌在另一种浏览器上进行 api 调用,它将无法正常工作。仅当您在登录的同一浏览器中尝试 api 调用时才有效。

因此,在 C# 中,您必须使用某种类型的爬虫/http 客户端进行登录,并使用相同的方式进行 api 调用。

希望有帮助。

于 2013-11-27T14:23:50.607 回答