API:ログイン

From mediawiki.org
This page is a translated version of the page API:Login and the translation is 79% complete.
Outdated translations are marked like this.

MediaWiki API では、あなたのアプリケーションやクライアントが認証された利用者の資格情報とログインを提供する必要がある場合があります。それは以下の目的で行われます: (a) 情報のクエリやデータの変更操作、(b) 高いリクエスト数制限を持つ大規模なクエリの実行のためです。

認証するための 2 つの方法

MediaWiki 操作 API への認証方法は 2 つあります:

方法1. action=login

ボットやその他の非対話型アプリケーションは、可能であれば所有者専用 OAuth コンシューマーを使用する方がセキュリティ上より安全です。 利用できない場合や、クライアントに適用できない場合は、ボット パスワードを使用して login 操作を行えます。

APIの説明文書


action=login (lg)

(main | login)
  • This module requires write rights.
  • This module only accepts POST requests.
  • Source: MediaWiki
  • License: GPL-2.0-or-later

Log in and get authentication cookies.

This action should only be used in combination with Special:BotPasswords; use for main-account login is deprecated and may fail without warning. To safely log in to the main account, use action=clientlogin.

Specific parameters:
Other general parameters are available.
lgname

Username.

lgpassword

Password.

lgdomain

Domain (optional).

lgtoken

A "login" token retrieved from action=query&meta=tokens

POST リクエスト


上記のリクエストでの lgtoken は、API:トークン から取得されます

レスポンス

{  
   "login": {  
      "lguserid": 21,
      "result": "Success",
      "lgusername": "William"
   }
}

サンプル コード

MediaWiki JS

/*
	login.js
	MediaWiki API Demos
	Demo of `Login` module: Sending request to login
	MIT License
*/

var api = new mw.Api();

api.login( 'your_bot_username', 'your_bot_password' ).done( function ( data ) {
	console.log( 'You are logged in as ' + data.login.lgusername );
} );

JavaScript

/*
	edit.js

	MediaWiki API Demos
	Demo of `Login` module: Sending post request to login

	MIT license
*/

var request = require( 'request' ).defaults( { jar: true } ),
	url = 'https://test.wikipedia.org/w/api.php';

// Step 1: GET request to fetch login token
function getLoginToken() {
	var params = {
		action: 'query',
		meta: 'tokens',
		type: 'login',
		format: 'json'
	};

	request.get( { url: url, qs: params }, function ( error, res, body ) {
		var data;
		if ( error ) {
			return;
		}
		data = JSON.parse( body );
		loginRequest( data.query.tokens.logintoken );
	} );
}

// Step 2: POST request to log in.
// Use of main account for login is not
// supported. Obtain credentials via Special:BotPasswords
// (https://www.mediawiki.org/wiki/Special:BotPasswords) for lgname & lgpassword
function loginRequest( loginToken ) {
	var params = {
		action: 'login',
		lgname: 'bot_username',
		lgpassword: 'bot_password',
		lgtoken: loginToken,
		format: 'json'
	};

	request.post( { url: url, form: params }, function ( error, res, body ) {
		if ( error ) {
			return;
		}
		console.log( body );
	} );
}

// Start From Step 1
getLoginToken();

PHP

<?php

/*
    login.php

    MediaWiki API Demos
    Demo of `Login` module: Sending post request to login
    MIT license
*/

$endPoint = "https://test.wikipedia.org/w/api.php";

$login_Token = getLoginToken(); // Step 1
loginRequest( $login_Token ); // Step 2

// Step 1: GET request to fetch login token
function getLoginToken() {
	global $endPoint;

	$params1 = [
		"action" => "query",
		"meta" => "tokens",
		"type" => "login",
		"format" => "json"
	];

	$url = $endPoint . "?" . http_build_query( $params1 );

	$ch = curl_init( $url );
	curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
	curl_setopt( $ch, CURLOPT_COOKIEJAR, "/tmp/cookie.txt" );
	curl_setopt( $ch, CURLOPT_COOKIEFILE, "/tmp/cookie.txt" );

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

	$result = json_decode( $output, true );
	return $result["query"]["tokens"]["logintoken"];
}

// Step 2: POST request to log in. Use of main account for login is not
// supported. Obtain credentials via Special:BotPasswords
// (https://www.mediawiki.org/wiki/Special:BotPasswords) for lgname & lgpassword
function loginRequest( $logintoken ) {
	global $endPoint;

	$params2 = [
		"action" => "login",
		"lgname" => "your_bot_username",
		"lgpassword" => "your_bot_password",
		"lgtoken" => $logintoken,
		"format" => "json"
	];

	$ch = curl_init();

	curl_setopt( $ch, CURLOPT_URL, $endPoint );
	curl_setopt( $ch, CURLOPT_POST, true );
	curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query( $params2 ) );
	curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
	curl_setopt( $ch, CURLOPT_COOKIEJAR, "/tmp/cookie.txt" );
	curl_setopt( $ch, CURLOPT_COOKIEFILE, "/tmp/cookie.txt" );

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

	echo( $output );
}

Python

#!/usr/bin/python3

"""
    login.py

    MediaWiki API Demos
    Demo of `Login` module: Sending post request to login
    MIT license
"""

import requests

USERNAME = "your_bot_username"
PASSWORD = "your_bot_password"

S = requests.Session()

URL = "https://www.mediawiki.org/w/api.php"

# Retrieve login token first
PARAMS_0 = {
    'action':"query",
    'meta':"tokens",
    'type':"login",
    'format':"json"
}

R = S.get(url=URL, params=PARAMS_0)
DATA = R.json()

LOGIN_TOKEN = DATA['query']['tokens']['logintoken']

print(LOGIN_TOKEN)

# Send a post request to login. Using the main account for login is not
# supported. Obtain credentials via Special:BotPasswords
# (https://www.mediawiki.org/wiki/Special:BotPasswords) for lgname & lgpassword

PARAMS_1 = {
    'action': "login",
    'lgname': USERNAME,
    'lgpassword': PASSWORD,
    'lgtoken': LOGIN_TOKEN,
    'format': "json"
}

R = S.post(URL, data=PARAMS_1)
DATA = R.json()

print(DATA)
assert DATA['login']['result'] == 'Success'
MediaWiki 1.27 以降、ログインにはメイン アカウントを使用することはサポートされていません。 資格情報は Special:BotPasswords で取得するか、clientlogin の方法を使用してください。 ログインおよびログインの維持には、クライアントがすべてのリクエストで正しい HTTP Cookie の処理を行う必要があります。 上記の Python の例では、セッション オブジェクト requests.Session() が Cookie を保持する方法を示しています。

起こりうるエラー

コード 情報
Failed Incorrect username or password entered. Please try again.
Failed Unable to continue login. Your session most likely timed out. (or you are not correctly handling cookies).
WrongToken Invalid token provided
NeedToken `lgtoken` not provided
Aborted login using the main account password rather than bot passwords
mustpostparams The following parameters were found in the query string, but must be in the POST body: $1.

方法2. クライアントログイン

カスタム エディターや巡回アプリケーションなどの対話型アプリケーションは、ウェブ ベースのユーザーインターフェイスへの完全な置換を意図せずにサービスを提供する場合には、clientlogin 操作を使用する必要があります。 ただし、ツールの認証に使用できる場合は、より簡単で安全な OAuth を使用することをお勧めします。 このモジュールは MediaWiki 1.27 以降で利用できます。

APIの説明文書


action=clientlogin (login)

(main | clientlogin)
  • This module requires write rights.
  • This module only accepts POST requests.
  • Source: MediaWiki
  • License: GPL-2.0-or-later

Log in to the wiki using the interactive flow.

The general procedure to use this module is:

  1. Fetch the fields available from action=query&meta=authmanagerinfo with amirequestsfor=login, and a login token from action=query&meta=tokens.
  2. Present the fields to the user, and obtain their submission.
  3. Post to this module, supplying loginreturnurl and any relevant fields.
  4. Check the status in the response.
    • If you received PASS or FAIL, you're done. The operation either succeeded or it didn't.
    • If you received UI, present the new fields to the user and obtain their submission. Then post to this module with logincontinue and the relevant fields set, and repeat step 4.
    • If you received REDIRECT, direct the user to the redirecttarget and wait for the return to loginreturnurl. Then post to this module with logincontinue and any fields passed to the return URL, and repeat step 4.
    • If you received RESTART, that means the authentication worked but we don't have a linked user account. You might treat this as UI or as FAIL.
Specific parameters:
Other general parameters are available.
loginrequests

Only use these authentication requests, by the id returned from action=query&meta=authmanagerinfo with amirequestsfor=login or from a previous response from this module.

Separate values with | or alternative.
Maximum number of values is 50 (500 for clients that are allowed higher limits).
loginmessageformat

Format to use for returning messages.

One of the following values: html, none, raw, wikitext
Default: wikitext
loginmergerequestfields

Merge field information for all authentication requests into one array.

Type: boolean (details)
loginpreservestate

Preserve state from a previous failed login attempt, if possible.

Type: boolean (details)
loginreturnurl

Return URL for third-party authentication flows, must be absolute. Either this or logincontinue is required.

Upon receiving a REDIRECT response, you will typically open a browser or web view to the specified redirecttarget URL for a third-party authentication flow. When that completes, the third party will send the browser or web view to this URL. You should extract any query or POST parameters from the URL and pass them as a logincontinue request to this API module.

logincontinue

This request is a continuation after an earlier UI or REDIRECT response. Either this or loginreturnurl is required.

Type: boolean (details)
logintoken

A "login" token retrieved from action=query&meta=tokens

This parameter is required.
*
This module accepts additional parameters depending on the available authentication requests. Use action=query&meta=authmanagerinfo with amirequestsfor=login (or a previous response from this module, if applicable) to determine the requests available and the fields that they use.
Examples:
Start the process of logging in to the wiki as user Example with password ExamplePassword.
api.php?action=clientlogin&username=Example&password=ExamplePassword&loginreturnurl=http://example.org/&logintoken=123ABC [open in sandbox]
Continue logging in after a UI response for two-factor auth, supplying an OATHToken of 987654.
api.php?action=clientlogin&logincontinue=1&OATHToken=987654&logintoken=123ABC [open in sandbox]

例1: 特別な認証拡張機能がないウィキの手順

POST リクエスト


上記のリクエストで API:トークン を介してトークンを取得してログインします。

レスポンス

{  
   "clientlogin":{  
      "status":"PASS",
      "username":"William"
   }
}

サンプル コード

clientlogin.py
#!/usr/bin/python3

"""
    clientlogin.py

    MediaWiki Action API Code Samples
    Demo of `clientlogin` module: Sending post request to login

    This demo app uses Flask (a Python web development framework).

    MIT license
"""

import requests
from flask import Flask, render_template, flash, request

S = requests.Session()
URL = "https://en.wikipedia.org/w/api.php"

# App config.
DEBUG = True
APP = Flask(__name__)
APP.config.from_object(__name__)
APP.config['SECRET_KEY'] = 'enter_your_secret_key'


@APP.route("/", methods=['GET', 'POST'])
def show_form():
    """ Render form template and handle form submission request """

    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        start_client_login(username, password)

    return render_template('clientlogin_form.html')

def start_client_login(username, password):
    """ Send a post request along with login token, user information
    and return URL to the API to log in on a wiki """

    login_token = fetch_login_token()

    response = S.post(url=URL, data={
        'action': "clientlogin",
        'username': username,
        'password': password,
        'loginreturnurl': 'http://127.0.0.1:5000/',
        'logintoken': login_token,
        'format': "json"
    })

    data = response.json()

    if data['clientlogin']['status'] == 'PASS':
        flash('Login success! Welcome, ' + data['clientlogin']['username'] + '!')
    else:
        flash('Oops! Something went wrong -- ' + data['clientlogin']['messagecode'])

def fetch_login_token():
    """ Fetch login token via `tokens` module """

    response = S.get(
        url=URL,
        params={
            'action': "query",
            'meta': "tokens",
            'type': "login",
            'format': "json"})
    data = response.json()
    return data['query']['tokens']['logintoken']

if __name__ == "__main__":
    APP.run()
form.html
<!DOCTYPE html>
  <title>MediaWiki Log in</title>
  <link rel="stylesheet" href="static/bootstrap/css/bootstrap.min.css">

<div class="container">
  <h2>MediaWiki Log in</h2>
  <form action="" method="post" role="form">
    <div class="form-group">
      <div class="form-field">
        <div class="label-field">Username</div>
        <input name="username">
      </div>
      <div class="form-field">
        <div class="label-field">Password</div>
        <input type="password" name="password">
      </div>
    </div>
    <button type="submit" class="btn btn-success">Log in</button>
  </form>
  <br>
  {% with messages = get_flashed_messages(with_categories=true) %}
  {% if messages %}
  {% for message in messages %}
  <div class="alert alert-info">
    {{ message[1] }}
  </div>
  {% endfor %}
  {% endif %}
  {% endwith %}
</div>
<br>
</div>
</div>

例2: 特別な認証拡張機能があるウィキの手順

ConfirmEdit (CAPTCHA)、OpenID Connect OATHAuth (二要素認証) などの特別な認証拡張機能があるウィキでは、より複雑な認証プロセスが行われる場合があります。 その場合、特定のフィールドが必要になることもありますが、それに関する説明は API:Authmanagerinfo クエリで取得できます。

ステップ1: キャプチャに回答し、OpenID認証を選択する

This documentation is an example and does not reflect the behavior of any specific currently-available OpenID extension.


クライアントは利用者のブラウザーを提供された redirecttarget にリダイレクトすることが期待されます。 OpenID プロバイダーが認証し、ウィキ上の Special:OpenIDConnectReturn にリダイレクトし、OpenID の応答を検証し、最初の API への POST で提供された codestate のパラメーターを追加して loginreturnurl にリダイレクトします。 この時点でクライアントがプロセスの制御を取り戻し、次の API リクエストを行います。
レスポンス
{
    "clientlogin": {
        "status": "REDIRECT",
        "redirecttarget": "https://openid.example.net/openid-auth.php?scope=openid&response_type=code&client_id=ABC&redirect_uri=https://wiki.example.org/wiki/Special:OpenIDConnectReturn&state=XYZ123",
        "requests": [
            {
                "id": "OpenIdConnectResponseAuthenticationRequest",
                "metadata": {},
                "required": "required",
                "provider": "OpenID Connect at example.net",
                "account": "",
                "fields": {
                    "code": {
                        "type": "string",
                        "label": "OpenID Code",
                        "help": "OpenID Connect code response"
                    },
                    "state": {
                        "type": "string",
                        "label": "OpenID State",
                        "help": "OpenID Connect state response"
                    },
                }
            }
        ]
    }
}
ここで、クライアントは利用者に対して現在のコードを二要素認証アプリで確認し、そのコードをサーバーに送信して認証プロセスを継続します。
レスポンス
{
    "clientlogin": {
        "status": "UI",
        "message": "Two-factor authentication",
        "requests": [
            {
                "id": "TwoFactorAuthenticationRequest",
                "metadata": {},
                "required": "required",
                "provider": "",
                "account": "",
                "fields": {
                    "code": {
                        "type": "string",
                        "label": "Code",
                        "help": "Two-factor authentication code"
                    }
                }
            }
        ]
    }
}
特定の場合、例えば OpenID Connect 拡張機能が OpenID アカウントをローカル利用者にマッピングできない場合、RESTART のレスポンスを受け取る可能性があります。 この場合、クライアントはログイン プロセスを最初からやり直すか、アカウント作成に切り替えるかもしれません。いずれの場合も、一部の状態を保持するために loginpreservestate または createpreservestate パラメーターを渡します。
レスポンス
{
    "clientlogin": {
        "status": "PASS",
        "username": "Alice"
    }
}

追加的な注記

  • 匿名で編集できるウィキでは、ログインしなくても API 経由で編集できますが、ログインすることを強く推奨します。 非公開のウィキでは、あらゆる API 機能についてログインが必須です。
  • アプリケーションには独立した利用者アカウントを作成することをおすすめします。 これは特に、アプリケーションが自動編集を行ったり、大規模なクエリを実行したりする場合には重要です。 これにより、アプリケーションによって行われた変更を追跡しやすくなり、アプリケーションのアカウントに特別な権限を付与することが容易になります。
  • ログインしている利用者によって行われるべきリクエストを送信する場合、リクエストに assert=user パラメーターを追加して利用者がログインしているかどうかを確認します。 利用者がログインしていない場合、assertuserfailed エラー コードが返されます。 See API:Assert for details.
  • ボット権限を持つアカウントかどうかを確認するには、リクエストに assert=bot パラメーターを追加します。 アカウントがボット権限を持っていない場合、assertbotfailed エラー コードが返されます。 See API:Assert for details.

関連項目