如何使用PHP cURL登录mediawiki?
我试图将mediawiki集成到我的网站中,但遇到了问题。我认为问题与cookies有关,因为我从mediawiki API获得了成功 这是我的密码:如何使用PHP cURL登录mediawiki?,php,cookies,curl,mediawiki-api,Php,Cookies,Curl,Mediawiki Api,我试图将mediawiki集成到我的网站中,但遇到了问题。我认为问题与cookies有关,因为我从mediawiki API获得了成功 这是我的密码: function mw_session_manager($Action = "") { $Root = $_SERVER['SERVER_ADDR']; $API_Location = "${Root}/w/api.php"; $expire = 60*60*24*14 + time(); $CookieFileP
function mw_session_manager($Action = "")
{
$Root = $_SERVER['SERVER_ADDR'];
$API_Location = "${Root}/w/api.php";
$expire = 60*60*24*14 + time();
$CookieFilePath = tempnam("/tmp/thedirectory", "CURLCOOKIE");
$CookiePrefix = 'theprefix';
$Domain = 'thedomain';
if($Action == 'login')
{
// Retrieves email address and password from sign-in form
$Email = $_POST['LogInEmail'];
$LgPassword = $_POST['LogInPassword'];
// Query to retrieve username from database based on email. It is implied that authentication has already succeeded.
$Query = "SELECT Username FROM Accounts WHERE Email = '$Email'";
$ResultSet = mysql_query($Query);
$ResultArray = mysql_fetch_array($ResultSet);
$LgName = $ResultArray[0]; // Username
// set variables to use in curl_setopts
$PostFields = "action=login&lgname=$LgName&lgpassword=$LgPassword&format=php";
// first http post to sign in to MediaWiki
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$API_Location");
curl_setopt($ch, CURLOPT_POSTFIELDS, "$PostFields");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_COOKIEJAR, $CookieFilePath);
curl_setopt($ch, CURLOPT_COOKIEFILE, $CookieFilePath);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$ResultSerialized = curl_exec($ch);
curl_close($ch); // curl closed
$ResultUnserialized = unserialize($ResultSerialized);
$Token = $ResultUnserialized[login][token];
// cookie must be set using session id from first response
$WikiSessionID = $ResultUnserialized[login][sessionid];
setcookie("${CookiePrefix}_session", $WikiSessionID, $expire, '/', $Domain);
// second http post to finish sign in
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$API_Location");
curl_setopt($ch, CURLOPT_POSTFIELDS, "action=login&lgname=${LgName}&lgpassword=${LgPassword}&lgtoken=${Token}&format=php");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_COOKIEJAR, $CookieFilePath);
curl_setopt($ch, CURLOPT_COOKIEFILE, $CookieFilePath);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$ResultSerialized = curl_exec($ch);
curl_close($ch); // curl closed
$ResultUnserialized = unserialize($ResultSerialized);
// set persistent cookies
$LgToken = $ResultUnserialized["login"]["lgtoken"];
$LgUserID = $ResultUnserialized["login"]["lguserid"];
$LgUserName = $ResultUnserialized["login"]["lgusername"];
setcookie("${CookiePrefix}UserName", $LgUserName, $expire, '/', $Domain);
setcookie("${CookiePrefix}UserID", $LgUserID, $expire, '/', $Domain);
setcookie("${CookiePrefix}Token", $LgToken, $expire, '/', $Domain);
// Delete cURL cookie
unlink($CookieFilePath);
return $somedebuggingvariable;
}
if($Action = "logout")
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$API_Location");
curl_setopt($ch, CURLOPT_POSTFIELDS, "action=logout");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_COOKIEJAR, $CookieFilePath);
curl_setopt($ch, CURLOPT_COOKIEFILE, $CookieFilePath);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$ResultSerialized = curl_exec($ch);
$LogoutReturn = unserialize($ResultSerialized);
$_SESSION['APIReturn'] = $LogoutReturn;
curl_close($ch); // curl closed
// destroys persistent cookies and ends session
$expire = time() - 60*60*24*90;
setcookie('Session', '', $expire, '/', $Domain);
setcookie("${CookiePrefix}_session", '', $expire, '/', $Domain);
setcookie("${CookiePrefix}UserName", '', $expire, '/', $Domain);
setcookie("${CookiePrefix}UserID", '', $expire, '/', $Domain);
setcookie("${CookiePrefix}Token", '', $expire, '/', $Domain);
// delete cURL cookie
unlink($CookieFilePath);
}
}
我还注意到,如果我提供了一个错误的令牌,API仍然会返回一个成功,因此我也不能排除这一点
编辑:我现在已经让它工作得很好,并将代码更新为当前的工作代码。看起来您正试图通过在网站上使用PHP脚本,使用API将用户登录到MediaWiki,从而为您的网站和MediaWiki实现单点登录机制 问题是,虽然您的脚本确实使用用户的凭据成功登录到MediaWiki,但它没有将MediaWiki身份验证cookie传递回用户 有几种方法可以解决此问题:
- 也许最简单的解决方案是使用JavaScript/AJAX在客户端完全处理MediaWiki登录过程。这样,cookies将直接发送到用户的浏览器。当然,不利的一面是,对于不能或不想运行JavaScript的用户来说,这是行不通的(但您可以让他们以通常的方式登录MediaWiki)
- 您也可以只在服务器端执行登录过程的第一步(检索令牌),然后让客户端直接请求第二步URL,例如,将其用作返回HTML页面上不可见的
的源。这不需要JavaScript,但需要在服务器和客户端之间来回发送用户密码和登录令牌,这可能会导致安全问题。至少,您应该确保您访问了包含iframe
的页面,以便密码不会保存在浏览器缓存中iframe
- 由于您的网站和MediaWiki安装可能位于同一个域中,因此您也可以使用当前代码,然后执行如下操作:
setcookie( $cookieprefix . '_session', $sessionid ); setcookie( $cookieprefix . 'UserName', $lgusername ); setcookie( $cookieprefix . 'UserID', $lguserid ); setcookie( $cookieprefix . 'Token', $lgtoken );
- 最后,您还可以扭转这个问题,编写一个代理程序,将MediaWiki的用户身份验证委托给您网站的用户身份验证系统。这样做的好处是允许您将两个系统完全绑定在一起,以便它们使用相同的用户数据库和相同的身份验证cookie。(MediaWiki仍然坚持创建自己的用户记录来存储自己的元数据,但如果需要,编写AuthPlugin可以让您访问系统的身份验证部分。)
'login\u userid'
不应该是'login\u lguserid'
?)您确实应该启用错误日志记录(最好将报告级别设置为E\u ALL
)并修复您看到的任何警告。此外,成功登录后返回的lgtoken
值与第一次尝试后返回的token
值不同。在盲目尝试第二个API查询之前,还应该检查第一个API查询返回的内容。谢谢,它现在可以工作了!我现在手动设置cookies。我以前试过,我想我有一些成功,但是太少了,我以为我忘记了注销--我忘记了登录尝试之间需要5秒的时间。但是仍然有一个问题——如果我尝试登录失败,因为我没有等待足够长的时间,那么在我通过实际的mediawiki表单登录并注销之前,它不会让我再次通过API登录。我想你只需要等待5分钟的超时过期。如果需要,您可以在LocalSettings.php中通过设置(比如,$wgPasswordAttemptThrottle['seconds']=60)来降低它代码>。或者,您甚至可以使用if($\u server['REMOTE\u ADDR']=='127.0.0.1')$wgPasswordAttemptThrottle=false)之类的命令豁免来自同一服务器的请求进行限制代码>。(当然,如果您这样做,那么最好实现您自己的登录尝试限制。实际上,在任何情况下,这都是一个好主意。)我认为这不是限制问题。我刚刚关闭了节流阀,我仍然有同样的问题。一次登录失败将阻止以后登录。即使成功,它也只在主页上注册为已登录,并且只有在登录后第一次访问主页时才注册。除非我在访问mediawiki页面之前等待15秒,否则它根本不会将我注册为已登录;如果我这样做,我会被完全锁定,直到我使用mediawiki登录表单登录;我不知道是什么原因造成的。API对失败的登录尝试(以及随后的登录尝试)报告了什么结果?好吧,我现在已经彻底解决了这个问题。原来浏览器缓存显示我仍然登录了一些页面;这与MediaWiki无关。现在已经完全修好了。我将更新代码,以防将来有人遇到类似问题。它现在内置了一个注销例程。谢谢你的帮助!