PowerShell操作MediaWiki获取CSRF Token失败问题排查
MediaWiki PowerShell脚本获取CSRF Token失败及编辑页面报错修复
问题根源分析
- 缺失登录流程:你的Wiki是私有配置(
$wgGroupPermissions['*']['read'] = false),所有操作必须先登录,但代码中Get-WebSession函数未实现,导致请求以匿名身份发送,API拒绝返回有效数据,进而触发Get-Member错误。 - 版本判断逻辑失效:
Get-Version函数未定义,导致代码错误进入MediaWiki 1.24以下的分支,而你的实际版本是1.39.3,应该使用新版的meta=tokens接口获取CSRF Token。 - 会话未复用:即使后续修复登录,若未统一复用会话对象,也会导致Token获取无效(返回
+\")。
修复步骤及代码
修改后的完整代码
Add-Type -AssemblyName System.Web $protocol = 'http://' $wiki = '10.10.10.95/' $api = 'api.php' $username = 'BotUser' $password = 'BotPass' # 全局变量存储会话和Token $global:websession = $null $global:csrftoken = $null # 登录函数:获取带登录状态的WebSession function Invoke-WikiLogin { if (-not $global:websession) { $uri = "$protocol$wiki$api" # 第一步:获取登录Token $loginTokenParams = @{ action = 'query' format = 'json' meta = 'tokens' type = 'login' } $loginTokenResponse = Invoke-WebRequest -Uri $uri -Method Get -Body $loginTokenParams $loginTokenJson = ConvertFrom-Json $loginTokenResponse.Content $loginToken = $loginTokenJson.query.tokens.logintoken # 第二步:执行登录 $loginParams = @{ action = 'login' format = 'json' lgname = $username lgpassword = $password lgtoken = $loginToken } $loginResponse = Invoke-WebRequest -Uri $uri -Method Post -Body $loginParams -SessionVariable global:websession $loginResult = ConvertFrom-Json $loginResponse.Content if ($loginResult.login.result -ne 'Success') { throw "登录失败:$($loginResult.login.reason)" } } return $global:websession } # 获取CSRF Token(针对MediaWiki 1.24+) function Get-CsrfToken { if (-not $global:csrftoken) { $uri = "$protocol$wiki$api" $session = Invoke-WikiLogin $tokenParams = @{ action = 'query' format = 'json' meta = 'tokens' type = 'csrf' } $tokenResponse = Invoke-WebRequest -Uri $uri -Method Get -Body $tokenParams -WebSession $session $tokenJson = ConvertFrom-Json $tokenResponse.Content $global:csrftoken = $tokenJson.query.tokens.csrftoken } return $global:csrftoken } # 编辑页面函数 function Edit-Page($title, $summary, $text) { $uri = "$protocol$wiki$api" $session = Invoke-WikiLogin $token = Get-CsrfToken $editParams = @{ action = 'edit' format = 'json' bot = '' title = $title summary = $summary text = $text token = $token } $editResponse = Invoke-WebRequest -Uri $uri -Method Post -Body $editParams -WebSession $session $editResult = ConvertFrom-Json $editResponse.Content if ($editResult.edit.result -ne 'Success') { throw "编辑页面错误:$($editResult.error.info)" } } # 测试流程 try { Write-Host "获取CSRF Token:$(Get-CsrfToken)" Edit-Page "Test_Page" "Bot Updated" "Page content goes here.." Write-Host "页面编辑成功" } catch { Write-Error $_ }
关键修复点说明
- 登录流程:补充了完整的MediaWiki API登录步骤,先获取登录Token,再提交用户名密码完成登录,确保会话携带登录状态。
- Token获取:直接使用MediaWiki 1.24+的
meta=tokens接口,避免旧分支的无效逻辑。 - 全局会话管理:使用
$global:关键字确保会话和Token在函数间共享,避免重复登录或获取无效Token。 - 错误处理:增加了登录和编辑的错误捕获,返回更清晰的错误信息。
内容的提问来源于stack exchange,提问作者Danfossi
相关产品推荐
相关产品推荐

