====== ログイン後にGETパラメーターを引き継ぐ ====== ===== 要求 ===== DokuWiki をベース CMS にしてアプリケーションを開発していると、未ログイン状態で認証が必要なページにアクセスした際、ログインページに飛ばされ、ログイン後に目的のページにリダイレクトされますが、その際、 URL にカスタムの GET パラメータがあった場合、ログイン後に消えてしまいます。リダイレクトされたページにもそれを引き継ぎたい、というのが今回の要求です。 これは DokuWiki 本体に手を入れるため、DokuWikiの更新で不具合が出るため、注意が必要! ===== 調査 ===== * 実際の認証処理は inc/auth.php で行っている。 * ログインページのフォームに hidden タグを埋め込んだりするのは ''inc/html.php::html_login:53'' 辺りで行っている。 * submit は通常の id を指定した ''doku.php?id="...:..."'' に対し POST で送られている ''do=login id=...:... sectok=""'' 等の POST パラメータが hidden で指定されている。 * 追加のパラメータは ''$INPUT->str('name')'' で取得できるらしい。''event_id'' であれば ''$INPUT->str('event_id')''、int 型であれば ''$INPUT->int('event_id')'' のような感じ。 * ''https://www.dokuwiki.org/devel:request_vars'' * ''inc/html.php::html_login'' を改造したものの、認証が成功した後はそのままページを表示せずに 302 リダイレクトしている。その際に不要なパラメータが削られている。。。 * ''inc/Action/Redirect.php:33'' 付近、$opts 配列に params プロパティを追加し、引継ぎたい GET パラメータの名前と値を連想配列で指定する * ''inc/Action/Redirect.php:59'' 付近、wl() への第二引数に先ほどの $opts に追加した params の連想配列を指定する。 ===== 実装 ===== バージョンアップにより、実装場所が変更になっている。inc/Ui/Login.php::show() /** * The loginform * * @author Andreas Gohr * * @param bool $svg Whether to show svg icons in the register and resendpwd links or not */ function html_login($svg = false){ global $lang; global $conf; global $ID; global $INPUT; print p_locale_xhtml('login'); print '
'.NL; $form = new Doku_Form(array('id' => 'dw__login', 'action'=> $ID)); $form->startFieldset($lang['btn_login']); $form->addHidden('id', $ID); $form->addHidden('do', 'login'); /** ここでログイン後に引継ぎたいパラメータを追加 **/ if ($INPUT->str('test')) $form->addHidden('test', $INPUT->str('test')); $form->addElement(form_makeTextField( 'u', ((!$INPUT->bool('http_credentials')) ? $INPUT->str('u') : ''), $lang['user'], 'focus__this', 'block') ); $form->addElement(form_makePasswordField('p', $lang['pass'], '', 'block')); if($conf['rememberme']) { $form->addElement(form_makeCheckboxField('r', '1', $lang['remember'], 'remember__me', 'simple')); } $form->addElement(form_makeButton('submit', '', $lang['btn_login'])); $form->endFieldset(); if(actionOK('register')){ $registerLink = (new \dokuwiki\Menu\Item\Register())->asHtmlLink('', $svg); $form->addElement('

'.$lang['reghere'].': '. $registerLink .'

'); } if (actionOK('resendpwd')) { $resendPwLink = (new \dokuwiki\Menu\Item\Resendpwd())->asHtmlLink('', $svg); $form->addElement('

'.$lang['pwdforget'].': '. $resendPwLink .'

'); } html_form('login', $form); print '
'.NL; }
/** * Redirect to the show action, trying to jump to the previously edited section * * @triggers ACTION_SHOW_REDIRECT * @throws ActionAbort */ public function preProcess() { global $PRE; global $TEXT; global $INPUT; global $ID; global $ACT; $opts = array( 'id' => $ID, 'preact' => $ACT, 'params' => [] ); /** 引継ぎたい GETパラメータを指定 **/ if ($INPUT->str('test')) $opts['params']['test'] = $INPUT->str('test'); //get section name when coming from section edit if($INPUT->has('hid')) { // Use explicitly transmitted header id $opts['fragment'] = $INPUT->str('hid'); } else if($PRE && preg_match('/^\s*==+([^=\n]+)/', $TEXT, $match)) { // Fallback to old mechanism $check = false; //Byref $opts['fragment'] = sectionID($match[0], $check); } // execute the redirect Event::createAndTrigger('ACTION_SHOW_REDIRECT', $opts, array($this, 'redirect')); // should never be reached throw new ActionAbort('show'); } /** * Execute the redirect * * Default action for ACTION_SHOW_REDIRECT * * @param array $opts id and fragment for the redirect and the preact */ public function redirect($opts) { $go = wl($opts['id'], $opts['params'], true, '&'); /** 第二引数を指定 **/ if(isset($opts['fragment'])) $go .= '#' . $opts['fragment']; //show it send_redirect($go); } ===== 課題 ===== DokuWikiソースに手を加えなくていいよう、Plugin 化したい。