3

mediawikiを自分のウェブサイトに統合しようとしていますが、問題があります。私はmediawikiAPIから成功を得ているので、問題はCookieに関係していると思います。

これが私のコードです:

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は成功を返すため、それを否定することもできません。

編集:私はそれが完全に機能するようになり、コードを現在の機能するコードに更新しました。

4

1 に答える 1

2

Web サイトに PHP スクリプトを作成し、API を使用してユーザーを MediaWiki にログインさせることで、Web サイトと MediaWiki にシングル サインオン メカニズムを実装しようとしているようです。

問題は、スクリプトが実際にユーザーの資格情報を使用して MediaWiki に正常にログインしているにもかかわらず、MediaWiki 認証 Cookie をユーザーに返していないことです。

この問題を解決するには、いくつかの方法があります。

  • おそらく最も簡単な解決策は、JavaScript / AJAX を使用してクライアント側で MediaWiki のログイン プロセスを完全に処理することです。そうすれば、Cookie はユーザーのブラウザに直接送信されます。もちろん、マイナス面は、これは JavaScript を実行できない、または実行したくないユーザーには機能しないことです (ただし、通常の方法で MediaWiki にログインさせることは常に可能です)。

  • また、ログイン プロセスの最初のステップ (トークンの取得) のみをサーバー側で実行し、クライアントに 2 番目のステップの URL を直接要求させることもiframeできます。これには JavaScript は必要ありませんが、サーバーとクライアントの間でユーザーのパスワードとログイン トークンをやり取りする必要があるため、セキュリティ上の問題が発生する可能性があります。少なくとも、 を含むページのキャッシュを無効iframeにして、パスワードがブラウザのキャッシュに保存されないようにする必要があります。

  • Web サイトと MediaWiki のインストールはおそらく同じドメインにあるため、現在のコードを使用して必要な Cookie を手動で設定することもできます。たとえば、次のようになります。

    setcookie( $cookieprefix . '_session', $sessionid );
    setcookie( $cookieprefix . 'UserName', $lgusername );
    setcookie( $cookieprefix . 'UserID',   $lguserid );
    setcookie( $cookieprefix . 'Token',    $lgtoken );
    
  • 最後に、問題を好転させ、代わりに MediaWiki のユーザー認証を Web サイトのユーザー認証システムに委譲するMediaWiki 認証プラグインを作成することもできます。これには、2 つのシステムを完全に結び付けて、同じユーザー データベースと同じ認証 Cookie を使用できるという利点があります。(MediaWiki は独自のメタデータを保存するために独自のユーザー レコードを作成することを今でも主張していますが、必要に応じて AuthPlugin を作成すると、システムの認証部分を完全にオーバーライドできます。)

于 2013-01-01T21:04:13.540 に答える