Как войти на сайт, используя новый параметр -form в pwsh

PowerShell 6.2.1 не возвращает свойство Forms, используя Invoke-WebRequest. В документе Microsoft Doc я вижу, что теперь есть параметр -Form, который вы можете использовать, но я взломал его уже несколько часов с очень небольшим успехом.

Как я делал это в Powershell 5

$r = Invoke-WebRequest -Uri 'somewebsite.com' -SessionVariable f
$f
$form = $r.Forms[0]

$form.Fields["userName"] = "username"
$form.Fields["brokerPassword"] = "password"

$login = Invoke-WebRequest -Uri 'somewebsite.com' -WebSession $f -Method 
POST -Body $form.Fields

В документе Microsoft Doc я вижу, что теперь есть параметр -Form, который вы можете использовать, но я взломал его уже несколько часов с очень небольшим успехом.

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=powershell-6

Они предоставили два возможных решения.

Пример 1

$Uri = 'https://api.contoso.com/v2/profile'
$Form = @{
firstName  = 'John'
lastName   = 'Doe'
email      = 'john.doe@contoso.com'
avatar     = Get-Item -Path 'c:\Pictures\jdoe.png'
birthday   = '1980-10-15'
hobbies    = 'Hiking','Fishing','Jogging'
}
$Result = Invoke-RestMethod -Uri $Uri -Method Post -Form $Form

Пример 2

$Body = @{
User = 'jdoe'
password = 'P@S$w0rd!'
}
$LoginResponse = Invoke-WebRequest 'http://www.contoso.com/login/' - 
SessionVariable 'Session' -Body $Body -Method 'POST'

$Session

$ProfileResponse = Invoke-WebRequest 'http://www.contoso.com/profile/' - 
WebSession $Session

$ProfileResponse

Я пробовал оба, и мой текущий блок кода является комбинацией двух, и это дает мне по крайней мере хороший сбой.

$username = 'useremail@gmail.com'
$password = 'p@ssw0rd'
$form = @{    
LoginForm_password = $password
LoginForm_username = $username
}
$result = Invoke-WebRequest 'https://www.podbean.com/login' - 
SessionVariable foo -Form $form -Method POST
$foo

$result | Get-Member | Format-table

Это ошибка, которую я сейчас получаю.

Invoke-WebRequest:

403 Запрещено

Запрещено У вас нет разрешения на доступ / вход на этом сервере.

В строке:7 символов: 11 + $ result = Invoke-WebRequest ' https://www.podbean.com/login' -SessionV... + ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CategoryInfo: InvalidOperation: (Метод: POST, Reque\u2026tent-Length: 357 }:HttpRequestMessage) [Invoke-WebRequest], HttpResponseException + FullyQualifiedErrorId: WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCmand

На самом деле это лучший ответ, который я получил.

1 ответ

Решение

Почему это, вероятно, не работает

На этом сайте использовалась защита от фальсификации сайтов с перекрестными запросами, которая скрывает скрытый скрытый элемент текстового поля в теле формы, чтобы гарантировать, что кто-то заходит на сайт, прежде чем разрешить им войти в систему. Вы можете убедиться в этом сами, просматривая HTML.

<div style="display:none">
    <input type="hidden" value="f8cbcfecec95c2405222c3cd0f951f6783aa329c" name="kdsowie31j4k1jlf913">
</div>

Когда я удаляю элементы стиля CSS display:none а также hiddenпоявится скрытое текстовое поле.

Когда вы заходите на этот сайт в обычном режиме, это значение также отправляется, и они узнают, что это вы.

Поскольку ваши запросы в PowerShell до сих пор не включали это критическое значение, вероятно, вы получили401и другие несанкционированные ошибки.

Вам нужно будет получить этот токен и отправить его, чтобы это работало.Вы не можете просто получить его один раз и жестко закодировать в свои сценарии, так как их значения обычно истекают после первого использования или каждые столько часов. Я проверил, и, похоже, они истекают очень быстро.

Получение токена

Получить этот токен не сложно. Поскольку это единственный скрытый элемент в форме, мы можем использовать этот атрибут для его извлечения.

$Request = Invoke-WebRequest -Uri https://www.podbean.com/login -SessionVariable Session -UseBasicParsing -UseDefaultCredentials
$TokenValue = ''
ForEach($field in $Request.InputFields){
    if ($field.type -eq 'hidden'){
        $TokenValue = [psCustomObject]@{Name=$field.name;Value=$field.Value}
    "Token value found! `n`t`tElement Name:`t$($TokenValue.Name)`n`t`tElement Value:`t$($TokenValue.Value)"
    }
}

Это отобразит следующее, когда будет найдено значение токена Antiforgery/CRSF.

Затем вы можете вставить это значение в вашу форму, как вы пытались сделать ранее, и посмотреть, куда оно вас приведет.

  $header = @{
    '__RequestVerificationToken' = $TokenValue
}

$form = @{
    $TokenValue.Name = $TokenValue.Value
    LoginForm_password = $password
    LoginForm_username = $username
}

$result = Invoke-WebRequest 'https://www.podbean.com/login' -header $header -SessionVariable Session -Form $form -Method POST

Вам придется немного поиграть с этим, но я думаю, что это должно привести вас на правильный путь. Если это не работает, я бы удалил$headerи посмотрим, поможет ли это. Я написал сообщение в блоге на эту тему и с более подробной информацией здесь, если вы хотите прочитать больше.

Более простой маршрут

PodBean также предлагает API, который вы можете использовать для входа в свои сервисы. Это было бы намного проще, чем то, что вы пытаетесь сделать, потому что вместо очистки форм или веб-автоматизации вы могли бы делать простые вызовы методов Rest, которые возвращали бы JSON. 9 раз из 10, если API существует, вы должны использовать его по этой простой причине:

Когда вы используете API, между вами и разработчиком сервиса существует "контракт". Они пообещают не слишком сильно что-то менять, чтобы не нарушать ваш рабочий процесс.

Если вы создаете сложную автоматизацию для этой системы входа в систему, ожидайте, что она сломается достаточно часто, чтобы раздражать, так как они могут изменить форму входа в систему, CSS или любую из множества вещей, которые могут привести вас к смерти.

Вот как можно начать с их API вместо этого. Они используют oAuth в качестве платформы аутентификации. У меня есть руководство по использованию PowerShell и oAuth, если вы застряли с oAuth. Если вы продолжите идти по пути oAuth и застрянете, сделайте еще один пост здесь, и я помогу вам там.

Другие вопросы по тегам