You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell操作MediaWiki获取CSRF Token失败问题排查

MediaWiki PowerShell脚本获取CSRF Token失败及编辑页面报错修复

问题根源分析

  1. 缺失登录流程:你的Wiki是私有配置($wgGroupPermissions['*']['read'] = false),所有操作必须先登录,但代码中Get-WebSession函数未实现,导致请求以匿名身份发送,API拒绝返回有效数据,进而触发Get-Member错误。
  2. 版本判断逻辑失效:Get-Version函数未定义,导致代码错误进入MediaWiki 1.24以下的分支,而你的实际版本是1.39.3,应该使用新版的meta=tokens接口获取CSRF Token。
  3. 会话未复用:即使后续修复登录,若未统一复用会话对象,也会导致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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 08:02:56