在GitHub API上使用带有用户名和密码的Invoke-WebRequest进行基本authentication

初始问题

使用cURL,我们可以通过HTTP Web请求传递一个用户名,如下所示:

$ curl -u <your_username> https://api.github.com/user 

-u标志接受authentication用户名,然后cURL将要求input密码。 cURL的例子是用GitHub Api进行基本authentication 。

我们如何同样传递用户名和密码以及Invoke-WebRequest? 最终目标是在GitHub API中使用带有基本身份validation的PowerShell。

编辑(这是什么工作)

注意事项来自维基百科在客户端的基本身份validation 。

将用户名和密码组合成单个stringusername:password

 $user = "shaunluttin" $pass = "super-strong-alpha-numeric-symbolic-long-password" $pair = "${user}:${pass}" 

将string编码为Base64的RFC2045-MIME变体,但不限于76字符/行。

 $bytes = [System.Text.Encoding]::ASCII.GetBytes($pair) $base64 = [System.Convert]::ToBase64String($bytes) 

创buildAuth值作为方法,一个空格,然后编码对Method Base64String

 $basicAuthValue = "Basic $base64" 

创build标题Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

 $headers = @{ Authorization = $basicAuthValue } 

调用Web请求

 Invoke-WebRequest -uri "https://api.github.com/user" -Headers $headers 

感谢@briantist的帮助!

讨论

PowerShell版本比cURL版本更为冗长。 这是为什么? @briantist指出,GitHub正在打破RFC,PowerShell正在坚持。 这是否意味着curl也违背了标准?

我在这里假设基本身份validation。

 $cred = Get-Credential Invoke-WebRequest -Uri 'https://whatever' -Credential $cred 

您可以通过其他方式( Import-Clixml等)获取您的凭证,但它必须是[PSCredential]对象。

根据评论编辑:

GitHub打破了RFC,因为他们在你提供的链接中解释:

API支持RFC2617中定义的基本身份validation,但有一些细微差别。 主要区别在于RFC要求未经授权的请求被401未经授权的响应回答。 在很多地方,这会揭示用户数据的存在。 相反,GitHub API以404 Not Found响应。 这可能会导致假设401未经授权的HTTP库的问题。 解决scheme是手动制作授权标题。

Powershell的Invoke-WebRequest在我所知的情况下在发送凭证之前等待401响应,而且由于GitHub从不提供凭证,因此您的凭证永远不会被发送。

手动构build标题

相反,你必须自己创build基本的auth头文件。

基本authentication需要一个由冒号user:pass分隔的用户名和密码组成的stringuser:pass ,然后发送Base64编码的结果。

这样的代码应该工作:

 $user = 'user' $pass = 'pass' $pair = "$($user):$($pass)" $encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($pair)) $basicAuthValue = "Basic $encodedCreds" $Headers = @{ Authorization = $basicAuthValue } Invoke-WebRequest -Uri 'https://whatever' -Headers $Headers 

显然你可以在这里结合一些string连接,但我想打破它,使其更清晰。

用这个:

 $root = 'REST_SERVICE_URL' $user = "user" $pass= "password" $secpasswd = ConvertTo-SecureString $pass -AsPlainText -Force $credential = New-Object System.Management.Automation.PSCredential($user, $secpasswd) $result = Invoke-RestMethod $root -Credential $credential