API: Kháu-tsō tshòng-kiàn
| This page is part of the MediaWiki Action API documentation. |
| MediaWiki version: | ≥ 1.27 |
API bûn-kiānn
Tshòng-kiàn kháu-tsō
Tsit-ê kuè-tîng hun-tsò sann-ê pōo-sòo:
- Fetch the fields from API:Authmanagerinfo and the token from API:Tokens.
- Send a POST request with the fetched token, user information and other fields, and return URL to the API.
- Deal with the response, which might involve further POST requests to supply more information.
Sī-lē 1: Teh bô ti̍k-sû sin-hūn giām-tsìng khok-tián ê wiki tíng-kuân tsìn-hîng tshú-lí
A wiki without special authentication extensions can be rather straightforward. If your code knows which fields will be required, it might skip the call to API:Authmanagerinfo and just assume which fields will be needed (i.e. username, password & retyped password, email, possibly realname).
reason parameter to the POST request. You could also use mailpassword in place of password and retype parameters to have MediaWiki send the new user a temporary password via email.
POST tshíng-kiû
Huê-ìng
{
"createaccount": {
"status": "PASS",
"username": "Zane"
}
}
Sī-lē tāi-bé
Python
#!/usr/bin/python3
"""
create_account.py
MediaWiki API Demos
Demo of `createaccount` module: Create an account on a wiki without the
special authentication extensions
MIT license
"""
import requests
S = requests.Session()
WIKI_URL = "http://dev.wiki.local.wmftest.net:8080"
API_ENDPOINT = WIKI_URL + "/w/api.php"
# First step
# Retrieve account creation token from `tokens` module
PARAMS_0 = {
'action':"query",
'meta':"tokens",
'type':"createaccount",
'format':"json"
}
R = S.get(url=API_ENDPOINT, params=PARAMS_0)
DATA = R.json()
TOKEN = DATA['query']['tokens']['createaccounttoken']
# Second step
# Send a post request with the fetched token and other data (user information,
# return URL, etc.) to the API to create an account
PARAMS_1 = {
'action': "createaccount",
'createtoken': TOKEN,
'username': 'your_username',
'password': 'your_password',
'retype': 'retype_your_password',
'createreturnurl': WIKI_URL,
'format': "json"
}
R = S.post(API_ENDPOINT, data=PARAMS_1)
DATA = R.json()
print(DATA)
PHP
<?php
/*
create_account.php
MediaWiki API Demos
Demo of `createaccount` module: Create an account on a wiki without the
special authentication extensions
MIT license
*/
$wikiUrl = "http://dev.wiki.local.wmftest.net:8080";
$endPoint = $wikiUrl . "/w/api.php";
$createAccount_Token = getCreateAccountToken(); // Step 1
createAccount( $createAccount_Token ); // Step 2
// Step 1: GET request to fetch createaccount token
function getCreateAccountToken() {
global $endPoint;
$params1 = [
"action" => "query",
"meta" => "tokens",
"type" => "createaccount",
"format" => "json"
];
$url = $endPoint . "?" . http_build_query( $params1 );
$ch = curl_init( $url );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_COOKIEJAR, "cookie.txt" );
curl_setopt( $ch, CURLOPT_COOKIEFILE, "cookie.txt" );
$output = curl_exec( $ch );
curl_close( $ch );
$result = json_decode( $output, true );
return $result["query"]["tokens"]["createaccounttoken"];
}
// Step 2: POST request with the fetched token and other data (user information,
// return URL, etc.) to the API to create an account
function createAccount( $createAccount_Token ) {
global $endPoint, $wikiUrl;
$params2 = [
"action" => "createaccount",
"createtoken" => $createAccount_Token,
"username" => "your_username",
"password" => "your_password",
"retype" => "retype_your_password",
"createreturnurl" => $wikiUrl,
"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, "cookie.txt" );
curl_setopt( $ch, CURLOPT_COOKIEFILE, "cookie.txt" );
$output = curl_exec( $ch );
curl_close( $ch );
echo( $output );
}
JavaScript
/*
create_account.js
MediaWiki API Demos
Demo of `createaccount` module: Create an account on a wiki without the
special authentication extensions
MIT license
*/
var request = require('request').defaults({jar: true}),
wikiUrl = "http://dev.wiki.local.wmftest.net:8080",
endPoint = wikiUrl + "/w/api.php";
// Step 1: GET request to fetch createaccount token
function getCreateAccountToken() {
var params_0 = {
action: "query",
meta: "tokens",
type: "createaccount",
format: "json"
};
request.get({ url: endPoint, qs: params_0 }, function (error, res, body) {
if (error) {
return;
}
var data = JSON.parse(body);
createaccount(data.query.tokens.createaccounttoken);
});
}
// Step 2: POST request with the fetched token and other data (user information,
// return URL, etc.) to the API to create an account
function createaccount(createaccount_token) {
var params_1 = {
action: "createaccount",
username: "your_username",
password: "your_password",
retype: "retype_your_password",
createreturnurl: wikiUrl,
createtoken: createaccount_token,
format: "json"
};
request.post({ url: endPoint, form: params_1 }, function (error, res, body) {
if (error) {
return;
}
console.log(body);
});
}
// Start From Step 1
getCreateAccountToken();
MediaWiki JS
/*
create_account.js
MediaWiki API Demos
Demo of `createaccount` module: Create an account on a wiki without the
special authentication extensions
MIT License
*/
var params = {
action: 'query',
meta: 'tokens',
type: 'createaccount',
format: 'json'
},
api = new mw.Api();
api.get( params ).done( function ( data ) {
var token = data.query.tokens.createaccounttoken,
params1 = {
action: 'createaccount',
username: 'your_username',
password: 'your_password',
retype: 'retype_your_password',
createreturnurl: 'http:' + mw.config.get( 'wgServer' ),
createtoken: token,
format: 'json'
};
api.post( params1 ).done( function ( data ) {
console.log( data );
} );
} );
Example: Account creation using authmanager (MediaWiki 1.27+)
This example shows the modern account creation flow using the authmanager-based API introduced in MediaWiki 1.27.
Special:ApiSandbox page, and API action as createaccount, the request can be constructed using the form presented (the "Additional parameters" section). You add the field names and their value. Create account token can be gotten using: /w/api.php?action=query&format=json&meta=tokens&type=createaccountThe response may include an authmanagerinfo object describing additional authentication steps (such as CAPTCHA or email verification).
Clients must inspect the requests array and submit follow-up requests until the account creation process is completed.
Sī-lē 2: Teh tuah-ū CAPTCHA khok-tián miâ ê wiki tíng-kuân tsìn-hîng tshú-lí
Note the first step below could, if you'd rather, be done as two steps: one to fetch the fields available from API:Authmanagerinfo and another to fetch the token from API:Tokens.
1. Fetch fields available from API:Authmanagerinfo and token from API:Tokens
| Result |
|---|
{
"batchcomplete": "",
"query": {
"authmanagerinfo": {
"canauthenticatenow": "",
"cancreateaccounts": "",
"preservedusername": "",
"requests": [
{
"id": "CaptchaAuthenticationRequest",
"metadata": {
"type": "image",
"mime": "image/png"
},
"required": "required",
"provider": "CaptchaAuthenticationRequest",
"account": "CaptchaAuthenticationRequest",
"fields": {
"captchaId": {
"type": "hidden",
"value": "16649214",
"label": "CAPTCHA ID",
"help": "This value should be sent back unchanged."
},
"captchaInfo": {
"type": "null",
"value": "/w/index.php?title=Special:Captcha/image&wpCaptchaId=16649214",
"label": "To help protect against automated account creation, please enter the words that appear below in the box ([[Special:Captcha/help|more info]]):",
"help": "Description of the CAPTCHA."
},
"captchaWord": {
"type": "string",
"label": "CAPTCHA",
"help": "Solution of the CAPTCHA."
}
}
}
...
]
},
"tokens": {
"createaccounttoken": "1de8d3f8023305742e69db9e16b4d5365bd82f9c+\\"
}
}
}
|
2. Send a post request along with a create account token, user information and return URL
| Result |
|---|
{
"createaccount": {
"status": "PASS",
"username": "Zane"
}
}
|
Sī-lē tāi-bé
Note this code sample separates the API:Authmanagerinfo and API:Tokens requests, and generally assumes there will be a CAPTCHA and no other complications.
| create_account_with_captcha.py |
|---|
#!/usr/bin/python3
"""
create_account_with_captcha.py
MediaWiki Action API Code Samples
Demo of `createaccount` module: Create an account on a wiki with a special
authentication extension installed. This example considers a case of a wiki
where captcha is enabled through extensions like ConfirmEdit
(https://www.mediawiki.org/wiki/Extension:ConfirmEdit)
MIT license
"""
import requests
from flask import Flask, render_template, flash, request
S = requests.Session()
WIKI_URL = "https://test.wikipedia.org"
API_ENDPOINT = WIKI_URL + "/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 """
fields = get_form_fields()
captcha = fields['CaptchaAuthenticationRequest']
captcha_url = WIKI_URL + captcha['captchaInfo']['value']
captcha_id = captcha['captchaId']['value']
display_fields = []
user_fields = []
captcha_fields = []
for field in fields:
for name in fields[field]:
details = {
'name': name,
'type': fields[field][name]['type'],
'label': fields[field][name]['label']
}
if field != "CaptchaAuthenticationRequest":
user_fields.append(details)
else:
if name == 'captchaWord':
captcha_fields.append(details)
display_fields = user_fields + captcha_fields
if request.method == 'POST':
create_account(request.form, captcha_id)
return render_template('create_account_form.html', \
captcha=captcha_url, fields=display_fields)
def get_form_fields():
""" Fetch the form fields from `authmanagerinfo` module """
result = {}
response = S.get(url=API_ENDPOINT, params={
'action': 'query',
'meta': 'authmanagerinfo',
'amirequestsfor': 'create',
'format': 'json'
})
data = response.json()
query = data and data['query']
authmanagerinfo = query and query['authmanagerinfo']
fields = authmanagerinfo and authmanagerinfo['requests']
for field in fields:
if field['id'] in ('MediaWiki\\Auth\\UserDataAuthenticationRequest', \
'CaptchaAuthenticationRequest', 'MediaWiki\\Auth\\PasswordAuthenticationRequest'):
result[field['id']] = field['fields']
return result
def create_account(form, captcha_id):
""" Send a post request along with create account token, user information
and return URL to the API to create an account on a wiki """
createtoken = fetch_create_token()
response = S.post(url=API_ENDPOINT, data={
'action': 'createaccount',
'createtoken': createtoken,
'username': form['username'],
'password': form['password'],
'retype': form['retype'],
'email': form['email'],
'createreturnurl': 'http://127.0.0.1:5000/',
'captchaId': captcha_id,
'captchaWord': form['captchaWord'],
'format': 'json'
})
data = response.json()
createaccount = data['createaccount']
if createaccount['status'] == "PASS":
flash('Success! An account with username ' + \
form['username'] + ' has been created!')
else:
flash('Oops! Something went wrong -- ' + \
createaccount['messagecode'] + "." + createaccount['message'])
def fetch_create_token():
""" Fetch create account token via `tokens` module """
response = S.get(url=API_ENDPOINT, params={
'action': 'query',
'meta': 'tokens',
'type': 'createaccount',
'format': 'json'
})
data = response.json()
return data['query']['tokens']['createaccounttoken']
if __name__ == "__main__":
APP.run()
|
| create_account_form.html |
|---|
<!DOCTYPE html>
<title>MediaWiki Create Account</title>
<!-- CSS files are in here: https://github.com/srish/MediaWiki-Action-API-Code-Samples/tree/master/static -->
<link rel="stylesheet" href="static/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="static/css/account_form.css">
<div class="container">
<h2>Create MediaWiki Account</h2>
<form method="POST">
<div class="form-group">
<div class="form-field">
<div class="label-field">Enter your username</div>
<input name="username">
</div>
<div class="form-field">
<div class="label-field">Password</div>
<input type="password" name="password">
</div>
<div class="form-field">
<div class="label-field">Confirm password</div>
<input type="password" name="confirm-password">
</div>
<div class="form-field">
<div class="label-field">Enter address (optional)</div>
<input name="email">
</div>
<div class="form-field">
<div class="label-field">Enter the text you see on the image below</div>
<input name="captcha-word">
</div>
<img src="{{ captcha }}">
</div>
<button type="submit" class="btn btn-success">Create your account</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>
|
Sī-lē 3: Teh í-king khé-iōng ê CAPTCHA, OpenID khok-tián hām siang in-sòo sin-hūn giām-tsìng khok-tián ê wiki tíng-kuân tshòng-kiàn kháu-tsō
<span id="1._Fetch_fields_available_from_API:Authmanagerinfo_and_token_from_API:Tokens">
Tē-it pōo: Uì API:Authmanagerinfo lāi-té hi̍k-tshú ē-tàng iōng ê jī-tuānn, uì API:Tokens lāi-té hi̍k-tshú līng-pâi
The fetching of API:Authmanagerinfo and API:Tokens is largely the same as in the previous example, and so is not repeated here. The list of requests returned by API:Authmanagerinfo will include definitions for both the CAPTCHA extension and the OpenID extension.
2. Answer the CAPTCHA and select OpenID authentication.
| Result |
|---|
{
"createaccount": {
"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"
},
}
}
]
}
}
|
The client would be expected to redirect the user's browser to the provided redirecttarget.
OpenID thê-kiong-tsiá tio̍h beh tsìn-hîng sin-hūn giām-tsìng, pīng tiông tīng-hiòng kàu wiki tíng-kuân ê Special:OpenIDConnectReturn, tse tio̍h giām-tsìng OpenID ê hióng-ìng, liân-āu tiông tīng-hiòng kàu teh API ê tē-1 ê POST lāi-té thê-kiong ê createreturnurl iā-koh thiam-ka code hām state tsit nn̄g-ê tsham-sòo.
The client gets control of the process back at this point and makes its next API request.
3. Back from OpenID.
The client posts the code and state back to the API. The API's response has the two-factor authentication extension prompting the user to set up their second factor.
| Result |
|---|
{
"createaccount": {
"status": "UI",
"message": "Set up two-factor authentication",
"requests": [
{
"id": "TwoFactorAuthenticationRequest",
"metadata": {
"account": "Alice",
"secret": "6CO3 2AKV EP2X MIV5"
},
"required": "optional",
"provider": "",
"account": "",
"fields": {
"2FAInfo": {
"type": "null",
"label": "A bunch of text describing how to set up two-factor auth.",
"help": "Two-factor authentication setup instructions"
},
"code": {
"type": "string",
"label": "Code",
"help": "Two-factor authentication code"
}
}
},
{
"id": "MediaWiki\\Auth\\ButtonAuthenticationRequest:skip2FASetup",
"metadata": {},
"required": "optional",
"provider": "MediaWiki\\Auth\\ButtonAuthenticationRequest",
"account": "MediaWiki\\Auth\\ButtonAuthenticationRequest:skip2FASetup",
"fields": {
"skip2FASetup": {
"type": "button",
"label": "Skip",
"help": "Skip two-factor authentication setup"
}
}
}
]
}
}
|
Now the client would prompt the user to set up a new account in their two-factor authentication app and enter the current code, or allow the user to skip 2FA setup. Let's assume the user does set up 2FA.
4. Set up two-factor authentication.
| Result |
|---|
{
"createaccount": {
"status": "PASS",
"username": "Alice"
}
}
|
The account creation has finally succeeded.
If at any point account creation fails, a response with status FAIL will be returned, along with a message to display to the user.
Khó-lîng tshò-ngōo
| Tāi-bé | Tsu-sìn |
|---|---|
| badtoken | Bô-hāu tshòng-kiàn kháu-tsō līng-pâi |
| notoken | token參數必須被設定。 |
| mustpostparams | 在查詢字串裡找出以下參數,而這應必須在 POST 正文裡:createtoken。 |
| missingparam | 參數"createcontinue" kap"createreturnurl"其一為必要。 |
| authmanager-create-no-primary | 提供的憑證不能用於帳號建立。 |
| noemailcreate | Lí ài thê-kiong ha̍p-lí ê tiān-chú-phoe chū-chí. |
| invalidemailaddress | 無法接受格式不正確的電子郵件地址,請輸入正確的電子郵件地址格式或略過填寫該欄位。 |
| badretype | Lí su-ji̍p ê 2-cho· bi̍t-bé bô tùi. |
| userexists | Lí phah ê iōng-chiá miâ-chheng í-keng ū lâng iōng. Chhiáⁿ lí iōng pa̍t-ê miâ. |
| captcha-createaccount-fail | 驗證碼錯誤或遺失。 |
| acct_creation_throttle_hit | 在最近$2此 wiki 上有訪客使用了您的 IP 地址建立了 num 個帳號,已達到在此時段裡的最大允許數量。
因此,目前使用該 IP 地址的訪客將無法建立更多的帳號。 如果您目前正在投入貢獻維基媒體專案相關活動的話,請查看請求臨時提升 IP 權限來協助解決此問題。 |
Hù-ka tsù-kái
- Account creations are recorded in Special:log/newusers.
If you are logged in, your username will also be recorded when creating an account.
- While executing the code snippets provided on this page, remember:
- Once an account on a wiki is created, it cannot be deleted.
- Always use
https://test.wikipedia.org/w/api.phpas the endpoint, so that you don't accidentally create accounts on production wikis.
- MediaWiki site administrators and extension developers can disable this API feature by inserting the following line in the configuration file:
$wgAPIModules['createaccount'] = 'ApiDisabled';