既に mediawiki をインストールしていますが、ユーザーを外部認証フォームから認証させたいと考えています。ユーザーが正しいユーザー名とパスワードを入力すると、Wiki ページにリダイレクトされ、ログイン データを再入力する必要がないため、移動できます。彼らが望む方法で wiki を編集するにはどうすればよいですか?
質問する
2933 次
3 に答える
3
action=login で mediawiki API を使用します。http://en.wikipedia.org/w/api.phpを参照
于 2009-07-09T21:46:26.793 に答える
0
https://www.mediawiki.org/wiki/User:Krinkle/API_PHP_cURL_exampleも参照してください
簡単なコード:
<?php
// Retrieves email address and password from sign-in form
$Username = array_key_exists('username',$_REQUEST)?$_REQUEST['username']:'';
$Password = array_key_exists('password',$_REQUEST)?$_REQUEST['password']:'';
$Action = array_key_exists('action',$_REQUEST)?$_REQUEST['action']:'';
$API_Location = "http://127.0.0.1/w/api.php";
//copied from LocalSettings.php
$wgDBtype = "mysql";
$wgDBserver = "localhost";
$wgDBname = "wiki";
$wgDBuser = "myuser";
$wgDBpassword = "12312312";
$CookiePrefix = 'wiki';
$expire = 60*60*24*365*5 + time();
$CooiePath= null; //='/';
$CookieDomain = null; //'example.com';
function encodeURIComponent($str) {
$revert = array('%21'=>'!', '%2A'=>'*', '%27'=>"'", '%28'=>'(', '%29'=>')');
return strtr(rawurlencode($str), $revert);
}
class curl_onHeaders
{
public $result=array();
function onHeader( $curl, $header_line ) {
$this->result[]=$header_line;
return strlen($header_line);
}
}
function curl($method,$url,$data=false,$headers=false)
{
//$method="PUT"
//$url ="http://example.com";
//$data = "The updated text message";
//$headers=array(); $headers[] = 'Accept: text/html';
$ch = curl_init();
if($data!==false)
{
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch,CURLOPT_POSTFIELDS,$data); // any post data, a string like param1=a¶m2=b
}
if($headers!==false)
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); //for updating we have to use PUT method.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$onHeader = new curl_onHeaders();
curl_setopt($ch, CURLOPT_HEADERFUNCTION, array(&$onHeader, 'onHeader'));
$result = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$object = new stdClass();
$object->result = $result;
$object->code = $code;
$object->headers = $onHeader->result;
if(curl_errno($ch))
throw new Exception("curl error: ". curl_error($ch));
//$object->error =curl_error($ch);
return $object;
}
function getcookies($headers)
{
$cookies='';
foreach( $headers as $header)
{
if (preg_match('/^Set-Cookie:\s*([^;]*)/mi', $header, $cookie) == 1)
{
if($cookies==='')
$cookies = $cookie[1];
else
$cookies .="; ".$cookie[1];
}
}
return $cookies;
}
function mearge_cookies($old,$new)
{
// cookies like session are sent only once from server, multiple cookies generally can be mearged with "; "
// a cookie jar is prefered but this code generally fine.
// folowing code does not handle expires
//
// cookie format: https://msdn.microsoft.com/en-us/library/windows/desktop/aa384321(v=vs.85).aspx
//
// Set-Cookie: <name>=<value>[; <name>=<value>]...
// [; expires=<date>][; domain=<domain_name>]
// [; path=<some_path>][; secure][; httponly]
//
// <date> format:
// DAY, DD-MMM-YYYY HH:MM:SS GMT
// DAY The day of the week (Sun, Mon, Tue, Wed, Thu, Fri, Sat).
// DD The day in the month (such as 01 for the first day of the month).
// MMM The three-letter abbreviation for the month (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec).
// YYYY The year.
// HH The hour value in military time (22 would be 10:00 P.M., for example).
// MM The minute value.
// SS The second value.
$cookiesa=array();
$cookies_strs_to_merge=array($old,$new);
foreach($cookies_strs_to_merge as $cookies_str)
{
foreach(preg_split("/\\s*;\\s*/",$cookies_str) as $cookie)
{
$pcookie=preg_split("/\\s*=\\s*/",$cookie);
$cookie_name=$pcookie[0];
$cookie_value=$pcookie[1];
if(sizeof($pcookie)>1)
{
if($cookie_name=='domain') continue;
if($cookie_name=='expires') continue;
if($cookie_name=='path') continue;
$cookiesa[$cookie_name]=$cookie_value;
}
else if($cookie=='secure' )continue;
else if($cookie=='httponly' )continue;
}
}
$cookies='';
foreach($cookiesa as $cookie_name=>$cookie_value)
$cookies.=($cookies===''?'':'; ').$cookie_name.'='.$cookie_value;
return $cookies;
}
//echo mearge_cookies("aaa=vsdfvsdfv; bbb=asdfasdfasf","aaa=222; ccc=123123"); die;
//$res=curl("GET",'http://doodkin.com');
//$lastcookies=getcookies($res->headers);
//$res=curl("GET",'http://doodkin.com',false,array('Cookie: '.$lastcookies));
//$lastcookies=mearge_cookies($lastcookies, getcookies($res->headers) );
mysql_connect($wgDBserver, $wgDBuser, $wgDBpassword) or die('Could not connect: ' . mysql_error());
if($Action == 'login')
{
// Query to retrieve username from database based on email. It is implied that authentication has already succeeded.
$Query = "SELECT Username FROM `$wgDBname`.Accounts WHERE Email = '".mysql_escape_string($Username)."'";
$ResultSet = mysql_query($Query);
if(mysql_num_rows($Query))
{
$ResultArray = mysql_fetch_array($ResultSet);
$Username = $ResultArray[0]; // Username
}
mysql_free_result($ResultSet);
// first http post to sign in to MediaWiki
$res=curl("POST",$API_Location,"action=login&lgname=".encodeURIComponent($Username)."&lgpassword=".encodeURIComponent($Password)."&format=php");
$lastcookies=getcookies($res->headers);
$result = unserialize($res->result);
$Token = $result[login][token];
// cookie must be set using session id from first response
$WikiSessionID = $result[login][sessionid];
setcookie("${CookiePrefix}_session", $WikiSessionID, $expire, $CooiePath, $CookieDomain);
// second http post to finish sign in
if ($result["login"]["result"] == "NeedToken") {
$res=curl("POST",$API_Location,"action=login&lgname=".encodeURIComponent($Username)."&lgpassword=".encodeURIComponent($Password)."&lgtoken=".encodeURIComponent($Token)."&format=php",array('Cookie: '.$lastcookies));
$result = unserialize($res->result);
}
if ($result["login"]["result"] == "Success") {
$error = 'ok';
// set persistent cookies
$LgToken = $result["login"]["lgtoken"];
$LgUserID = $result["login"]["lguserid"];
$LgUserName = $result["login"]["lgusername"];
$cookieprefix = $result["login"]["cookieprefix"];
if($cookieprefix!=$CookiePrefix) throw new Exception('notice a wrong cookie prefix');
$_COOKIE["${CookiePrefix}UserName"]=$LgUserName;
$_COOKIE["${CookiePrefix}UserID"]=$LgUserID;
$_COOKIE["${CookiePrefix}Token"]=$LgToken;
$_COOKIE["${CookiePrefix}_session"]=$WikiSessionID;
setcookie("${CookiePrefix}UserName", $LgUserName, $expire, $CooiePath, $CookieDomain);
setcookie("${CookiePrefix}UserID", $LgUserID, $expire, $CooiePath, $CookieDomain);
setcookie("${CookiePrefix}Token", $LgToken, $expire, $CooiePath, $CookieDomain);
} else if ($result["login"]["result"] == "NeedToken") {
$error = "Error 005: Token error. second request.";
} else if ($result["login"]["result"] == "NoName") {
$error = "The username can not be blank";
} else if ($result["login"]["result"] == "Illegal") {
$error = "You provided an illegal username";
} else if ($result["login"]["result"] == "NotExists") {
$error = "The username you provided doesn't exist";
} else if ($result["login"]["result"] == "EmptyPass") {
$error = "The password can not be blank";
} else if ($result["login"]["result"] == "WrongPass" || $result["login"]["result"] == "WrongPluginPass") {
$error = "The password you provided is incorrect";
} else if ($result["login"]["result"] == "CreateBlocked") {
$error = "Autocreation was blocked from this IP address";
} else if ($result["login"]["result"] == "Throttled") {
$error = "You've logged in too many times in a short time. Try again later.";
} else if ($result["login"]["result"] == "mustbeposted") {
$error = "Error 004: Logindata was not send correctly";
} else if ($result["login"]["result"] == "Blocked") {
$error = "This account is blocked.";
} else if ($result["login"]["result"]){
$error = "Error 001: An unknown event occurred.";
} else {
$error = "Error 002: An unknown event occurred.";
}
echo $error;
}
if($Action == "logout")
{
// first http post to sign in to MediaWiki
$_session = array_key_exists("${CookiePrefix}_session",$_COOKIE)?$_COOKIE["${CookiePrefix}_session"]:'';
$UserName = array_key_exists("${CookiePrefix}UserName",$_COOKIE)?$_COOKIE["${CookiePrefix}UserName"]:'';
$UserID = array_key_exists("${CookiePrefix}UserID",$_COOKIE)?$_COOKIE["${CookiePrefix}UserID"]:'';
$Token = array_key_exists("${CookiePrefix}Token",$_COOKIE)?$_COOKIE["${CookiePrefix}Token"]:'';
$headers=array( "Cookie: ".
"${CookiePrefix}_session=".encodeURIComponent($_session)."; ".
"${CookiePrefix}UserName=".encodeURIComponent($UserName)."; ".
"${CookiePrefix}UserID=".encodeURIComponent($UserID)."; ".
"${CookiePrefix}Token=".encodeURIComponent($Token) );
$res=curl("POST",$API_Location,"action=logout",$headers);
$LogoutReturn = unserialize($res->result);
// destroys persistent cookies and ends session
$expire = time() - 60*60*24*90;
setcookie('Session', '', $expire, $CooiePath, $CookieDomain);
setcookie("${CookiePrefix}_session", '', $expire, $CooiePath, $CookieDomain);
setcookie("${CookiePrefix}UserName", '', $expire, $CooiePath, $CookieDomain);
setcookie("${CookiePrefix}UserID", '', $expire, $CooiePath, $CookieDomain);
setcookie("${CookiePrefix}Token", '', $expire, $CooiePath, $CookieDomain);
unset($_COOKIE["${CookiePrefix}UserName"]);
unset($_COOKIE["${CookiePrefix}UserID"]);
unset($_COOKIE["${CookiePrefix}Token"]);
unset($_COOKIE["${CookiePrefix}_session"]);
echo "logout";
}
function checklogin()
{
global $CookiePrefix,$wgDBname;
if( array_key_exists("${CookiePrefix}_session",$_COOKIE)
&& array_key_exists("${CookiePrefix}UserID",$_COOKIE)
)
{
$UserID = intval($_COOKIE["${CookiePrefix}UserID"]);
$UserName = array_key_exists("${CookiePrefix}UserName",$_COOKIE)?$_COOKIE["${CookiePrefix}UserName"]:'';
$Token = array_key_exists("${CookiePrefix}Token",$_COOKIE)?$_COOKIE["${CookiePrefix}Token"]:'';
($result=mysql_query("Select user_name,user_real_name,user_email,user_token,user_token,(Select ug_user from `$wgDBname`.user_groups WHERE ug_group='sysop' and ug_user=user.user_id) as perms from `$wgDBname`.user user WHERE user_id=$UserID"))||die(mysql_error());
$udata=mysql_fetch_object($result);
mysql_free_result($result);
if ($udata!=null)
{
if ( $udata->perms!=null )
{
$level = 1;
}
if($UserName!=$udata->user_name)
{
echo "different username. cookie vs db. can not auto login from mediawiki";
return null;
}
if($Token!=$udata->user_token) {
echo "different token. cookie vs db. can not auto login from mediawiki";
return null;
}
return array(
'UniqueID' => $UserID,
'Name' => $UserName,
'Title' => $udata->user_real_name==""?NULL:$udata->user_real_name,
'Email' => $udata->user_email==""?'no@email.com':$udata->user_email,
'Admin' => $level
);
}
return null;
}
}
?>
<?
$user=checklogin();
if($user!=null)
{
?>
welcome <?=$user['Title']? $user['Title']:$user['Name'] ?>. <br>
<a href="<?=$_SERVER['PHP_SELF']?>?action=logout">logout</a>
<?
}
else
{
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>Signin</title>
<!-- Bootstrap core CSS -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/css/bootstrap.css" rel="stylesheet">
<!--[if eq IE 10]>
<style type="text/css">
/*!
* IE10 viewport hack for Surface/desktop Windows 8 bug
* http://getbootstrap.com/getting-started/#support-ie10-width
*/
@-webkit-viewport { width: device-width; }
@-moz-viewport { width: device-width; }
@-ms-viewport { width: device-width; }
@-o-viewport { width: device-width; }
@viewport { width: device-width; }
</style>
<![endif]-->
<!-- Custom styles for this template -->
<style type="text/css">
body {
padding-top: 40px;
padding-bottom: 40px;
background-color: #eee;
}
.form-signin {
max-width: 330px;
padding: 15px;
margin: 0 auto;
}
.form-signin .form-signin-heading,
.form-signin .checkbox {
margin-bottom: 10px;
}
.form-signin .checkbox {
font-weight: normal;
}
.form-signin .form-control {
position: relative;
height: auto;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
padding: 10px;
font-size: 16px;
}
.form-signin .form-control:focus {
z-index: 2;
}
.form-signin input[type="email"] {
margin-bottom: -1px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.form-signin input[type="password"] {
margin-bottom: 10px;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
</style>
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="container">
<form class="form-signin" action="<?=$_SERVER['PHP_SELF']?>" method="post" ><input type="hidden" name="action" value="login">
<h2 class="form-signin-heading">Please sign in</h2>
<label for="inputEmail" class="sr-only">Username or Email address</label>
<input type="text" id="inputEmail" class="form-control" name="username" placeholder="Username Or Email address" required autofocus>
<label for="inputPassword" class="sr-only">Password</label>
<input type="password" id="inputPassword" name="password" class="form-control" placeholder="Password" required>
<!-- <div class="checkbox">
<label>
<input type="checkbox" value="remember-me"> Remember me
</label>
</div> -->
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
</form>
</div> <!-- /container -->
<!--[if eq IE 10]>
<script type="application/javascript">
/*!
* IE10 viewport hack for Surface/desktop Windows 8 bug
* Copyright 2014-2015 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
// See the Getting Started docs for more information:
// http://getbootstrap.com/getting-started/#support-ie10-width
(function () {
'use strict';
if (navigator.userAgent.match(/IEMobile\/10\.0/)) {
var msViewportStyle = document.createElement('style')
msViewportStyle.appendChild(
document.createTextNode(
'@-ms-viewport{width:auto!important}'
)
)
document.querySelector('head').appendChild(msViewportStyle)
}
})();
</script>
<![endif]-->
</body>
</html>
<?
}
@mysql_close($conn);
?>
于 2016-02-15T17:19:11.003 に答える
0
Web 認証サービスを提供する外部認証サービスがある場合は、いくつかの webauth 拡張を適応させることができます。これは私の組織で使用されています。もちろん、カスタマイズする必要があります。
さらに別のオプションは、この拡張機能を使用したOpenIDログインで、stackoverflow ログインに似ています。
これら 2 つのソリューションでは、パスワードは「外部フォーム」とウィキの間で送信されず、ユーザーがログイン チャレンジに合格したことを示すトークンのみが送信されます。
于 2009-07-16T05:15:00.357 に答える