API:创建账号
| 本页是MediaWiki Action API帮助文档的一部分。 |
| MediaWiki版本: | ≥ 1.27 |
API帮助文档
创建账号
此流程有3個步驟:
- # 从API:Authmanagerinfo获取字段,从API:令牌获取令牌。
- # 使用获取的令牌、用户信息等字段发送POST请求,并将URL返回给API。
- # 处理返回结果,这可能涉及进一步的POST请求以提供更多信息。
示例1:没有特殊身份验证扩展的wiki的过程
在没有特殊身份验证扩展的wiki上处理是相当简单的。 如果你的代码知道哪些字段是必填的,它可以跳过对API:Authmanagerinfo的调用并假设需要哪些字段(即用户名,密码和重复输入的密码,邮箱,可能还有真名)。
reason参数说明原因。 你也可以用mailpassword代替password和retype,让MediaWiki发送含有临时密码的邮件给新用户。
POST请求
回应
{
"createaccount": {
"status": "PASS",
"username": "Zane"
}
}
示例代码
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.
示例2:有验证码扩展的wiki的过程
注意,如果你愿意,以下的第1步可以分成两步完成:先从API:Authmanagerinfo获取可用字段,再从API:令牌获取令牌。
<span id="1._Fetch_fields_available_from_API:Authmanagerinfo_and_token_from_API:令牌">
第1步:从API:Authmanagerinfo获取可用字段并从API:令牌获取令牌
| 结果 |
|---|
{
"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步:发送包含创建用户令牌和用户信息的post请求,并返回URL
| 结果 |
|---|
{
"createaccount": {
"status": "PASS",
"username": "Zane"
}
}
|
示例代码
注意,此代码示例将API:Authmanagerinfo和API:令牌请求分开,并且假设只有验证码没有其他复杂情况。
| 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>
|
示例3:在启用了验证码、OpenID和双重认证扩展的wiki上创建帐户
<span id="1._Fetch_fields_available_from_API:Authmanagerinfo_and_token_from_API:令牌">
第1步:从API:Authmanagerinfo获取可用字段并从API:令牌获取令牌
API:Authmanagerinfo和API:令牌的获取与上例大致相同,这里不再赘述。 从API:Authmanagerinfo返回的请求列表会包含验证码和OpenID扩展的定义。
第2步:填写验证码并选择OpenID身份验证。
| 结果 |
|---|
{
"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"
},
}
}
]
}
}
|
客户端会将用户的浏览器重定向到提供的redirecttarget。
OpenID会进行身份验证,并重定向到wiki上的Special:OpenIDConnectReturn。这会验证OpenID的返回结果,然后重定向到添加了code和state参数的第一个POST里所提供的loginreturnurl的API。
客户端此时重新获得对流程的控制权,并发出下一个API请求。
第3步:从OpenID返回。
客户端通过post请求,回传code和state给API. API的返回结果带有双重验证扩展,提示用户设置他们的第二重验证。
| 结果 |
|---|
{
"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"
}
}
}
]
}
}
|
现在客户端会提示用户在他们的双重验证应用程序上设置新账号并输入当前验证码,或跳过双重验证。 我们假设用户确实设置了2FA(双因素验证)。
第四步:设置双因素身份验证。
| 结果 |
|---|
{
"createaccount": {
"status": "PASS",
"username": "Alice"
}
}
|
帐户创建终于成功了。
如果在某一步账户创建失败, 用户会收到带有失败状态和信息的返回结果。
可能的错误
| 代码 | 信息 |
|---|---|
| badtoken | 无效的创建帐户令牌 |
| notoken | token参数必须被设置。 |
| mustpostparams | 以下参数在查询字符串中被找到,但必须在POST正文中:createtoken。 |
| missingparam | 需要"createcontinue"和"createreturnurl"中的至少一个参数。 |
| authmanager-create-no-primary | 提供的凭据不能用于账号创建。 |
| noemailcreate | 您需要提供一个有效的电子邮件地址。 |
| invalidemailaddress | 无法接受格式不正确电子邮件地址。请输入格式正确的地址,或将此字段留空。 |
| badretype | 您输入的密码不匹配。 |
| userexists | 输入的用户名已在使用,请选用其他名称。 |
| captcha-createaccount-fail | 验证码错误或丢失。 |
| acct_creation_throttle_hit | 在最近$2,使用您的IP地址访问此wiki的访客创建了num个账号,已达到此时间段内允许创建的最大账号数。因此,使用此IP地址的访客目前不能再创建更多账号。
如果向维基媒体项目作出贡献是您当前参加的活动的重要事项,请参见请求临时提升IP限制一文以帮助解决此问题。 |
附加提醒
- 帐户创建记录在Special:log/newusers。
如果您已登录,则在创建帐户时您的用户名也会被记录。
- 在执行此页面上提供的代码段时,请记住:
- 一旦创建维基上的帐户,将无法删除该帐户。
- 请始终使用终端
https://test.wikipedia.org/w/api.php,这样你就不会不小心在wiki的产品环境中创建账号。
- MediaWiki的站点管理员和扩展开发者可以通过在配置文件中插入以下代码来禁用此API功能:
$wgAPIModules['createaccount'] = 'ApiDisabled';