1
$ch=curl_init();
$postfield = "action=login&lgname=d&lgpassword=Password&format=json";
$url = "http://wiki.signa.com/api.php"; //url to wiki's api

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0); 
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfield);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);


$output = json_decode(curl_exec($ch));
curl_close($ch);

print_r($output);
$token = $output->login->token;
$session = $output->login->sessionid;

$ch=curl_init();

$postfield = "action=login&lgname=d&lgpassword=Password&lgtoken={$token}";
$url = "http://wiki.signa.com/api.php"; //url to wiki's api

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0); 
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfield);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

$output = curl_exec($ch);
curl_close($ch);

print_r($output);
die;

通过第一个请求,我得到了这个对象:

stdClass Object
(
    [login] => stdClass Object
        (
            [result] => NeedToken
            [token] => ad61fadb829e5cd44b0062463b7cc2d2
            [cookieprefix] => wikisign_mediawiki
            [sessionid] => ebb892881eed27554161234916d00480
        )

)

我正在使用令牌进行第二次请求,但我得到了 result = NeedToken. 应该是成功的,因为我现在正在发送令牌。

我注意到文档说:

使用 POST 发送登录请求,正文中包含确认令牌,enwiki_session标头中包含从先前请求返回的会话 cookie(例如 )。

我对此并不完全清楚。我假设我遇到了问题,因为我没有在标题中发送会话 cookie。我需要在第二个请求之前设置一个 cookie 吗?

4

2 回答 2

1

是的,您需要处理所有 Set-Cookie 标头才能成功登录。文档对此非常具体

此请求还将在 HTTP 标头中返回一个会话 cookie(Set-Cookie: enwikiSession=17ab96bd8ffbe8ca58a78657a918558e; path=/; domain=.wikipedia.org; HttpOnly),如果您的框架不这样做,您必须为第二个请求返回该 cookie自动地

一个成功的 action=login 请求将设置需要被视为已登录的 cookie。许多框架会自动处理这些 cookie(例如 cURL 中的 cookiejar)。如果是这样,请务必利用这一点。如果没有,最可靠的方法是从 HTTP 响应的 Set-Cookie 标头中解析它们。

于 2015-04-04T21:33:48.867 回答
1

这是一个老话题,但我会为感兴趣的人回答:) 事实上,您需要将 cookie 保存在一个文件中,并在第二次尝试登录时再次使用它们。类似的东西:

$path_cookie = 'connexion_temporaire.txt';
if (!file_exists($path_cookie)) touch($path_cookie); 


$postfields = array(
        'action' => 'login',
        'format'=> 'json',
        'lgname' => $login,
        'lgpassword' => $pass
);

$curl = curl_init();

curl_setopt($curl, CURLOPT_URL, $lienTestWiki);
curl_setopt($curl, CURLOPT_COOKIESESSION, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postfields);
curl_setopt($curl, CURLOPT_COOKIEJAR, $path_cookie); // you put your cookie in the file
$connexion=curl_exec($curl);
$json_connexion = json_decode($connexion, true);
$tokenConnexion=$json_connexion['login']['token']; // you take the token and keep it in a var for your second login

// /!\ don't close the curl conection or initialize a new one or your session id will change !

$postfields = array(
        'action' => 'login',
        'format'=> 'json',
        'lgtoken' => $tokenConnexion,
        'lgname' => $login,
        'lgpassword' => $pass

);


curl_setopt($curl, CURLOPT_URL, $lienTestWiki);
curl_setopt($curl, CURLOPT_COOKIESESSION, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postfields);
curl_setopt($curl, CURLOPT_COOKIEFILE, $path_cookie); //get the previous cookie
$connexionToken=curl_exec($curl);

var_dump($connexionToken); 

运行此程序时,您这次应该会看到成功 :)

于 2015-06-24T12:12:44.293 回答