简体   繁体   English

在 PowerShell 中为 Ghost 创建 JWT 令牌

[英]Create JWT token in PowerShell for Ghost

Update更新


Managed to work around my problem with this method from GhostSharp :使用GhostSharp中的此方法设法解决了我的问题:

    public static class ByteConvertor
    {
        public static byte[] StringToByteArray(string hex)
        {
            int NumberChars = hex.Length;
            byte[] bytes = new byte[NumberChars / 2];
            for (int i = 0; i < NumberChars; i += 2)
                bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
            return bytes;
        }
    }

Is there a better way to accomplish the same thing in C# or PowerShell?在 C# 或 PowerShell 中有没有更好的方法来完成同样的事情? Am I missing some method on Encoding or Convert that would help me solve this?我是否遗漏了一些可以帮助我解决此问题的编码或转换方法?


I'm trying to construct a JWT token to authenticate against my Ghost Blog, but all of their samples are in Javascript, Ruby and Python. Nothing in C# or PowerShell and I can't seem to make the correct conversion.我正在尝试构建一个 JWT 令牌来针对我的幽灵博客进行身份验证,但他们的所有样本都在 Javascript、Ruby 和 Python 中。C# 或 PowerShell 中没有任何内容,我似乎无法进行正确的转换。

This is the code I have right now:这是我现在的代码:

$parts = $adminToken -split ":"
$id = $parts[0]
$secret= $parts[1]

$secret= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($secret)) | ConvertFrom-Base64UrlString | ConvertTo-Base64UrlString

Install-Module -Name JWT

$jwtToken = New-Jwt -Header (@{
    "alg" = "HS256"
    "kid" = $id
    "typ" = "JWT"
}| ConvertTo-Json) -PayloadJson (@{
    "exp" = ([DateTimeOffset](Get-date).AddMinutes(5)).ToUnixTimeSeconds()
    "iat" = ([DateTimeOffset](Get-date)).ToUnixTimeSeconds()
    "aud" = "/admin/"
} | ConvertTo-Json) -Secret $secret

Invoke-RestMethod -Uri "https://scrumbug.ghost.io/ghost/api/admin/pages/$($trainingPage.id)" -Method PUT -Body ($trainingPage | ConvertTo-Json) -Headers @{Authorization="Ghost $jwtToken "}

But I keep getting complaints from Ghost that my token isn't correct:但我不断收到 Ghost 的投诉,说我的令牌不正确:

  50 |  Invoke-RestMethod -Uri "https://scrumbug.ghost.io/ghost/api/admin/pag …
     |  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | {"errors":[{"message":"Invalid token: invalid
     | signature","context":null,"type":"UnauthorizedError","details":null,"property":null,"help":null,"code":"INVALID_JWT","id":"069932a0-4009-11ed-afce-656a161cb24c","ghostErrorCode":null}]}

There are a number of samples in different languages , but I can't see what I'm missing anymore.有许多不同语言的样本,但我看不出我遗漏了什么。

I suspect my error is in this line:我怀疑我的错误在这一行:

$key = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($secret)) | ConvertFrom-Base64UrlString | ConvertTo-Base64UrlString

Which should be equivalent to:这应该等同于:

[secret].pack('H*')

Or:或者:

printf '%s' "${input}" | base64 | tr -d '=' | tr '+' '-' | tr '/' '_'

A sample token provided by Ghost in the admin panel used to construct the JWT token looks like $id:$secret : Ghost 在管理面板中提供的用于构造 JWT 令牌的示例令牌看起来像$id:$secret

THIS TOKEN HAS BEEN REVOKED AND IS NOT VALID.
644599e8733df7003d6fa66e:9aff4fdd6bb58957da5688a9cf0046a76bcc39b6b9ab16261123927f1caf5c94

It's indeed the conversion from the token to a byte[] that does the magic trick.确实是从令牌到 byte[] 的转换实现了魔术。

Thanks to a colleague, the magic line of code I was looking for is:感谢一位同事,我正在寻找的神奇代码行是:

[Convert]::FromHexString($secret)

Which does all the magic.哪个神奇。 Only works on PowerShell Core and .NET 5+.仅适用于 PowerShell Core 和 .NET 5+。

The full solution to my problem:我的问题的完整解决方案:

Install-Module -Name JWT

$token = "id:secret" # Your token here
$parts = $token -split ":"
$id = $parts[0]
$secretKey = $parts[1]
$secretBytes = [Convert]::FromHexString($secretKey)

$jwtToken = New-Jwt -Header (@{
    "alg" = "HS256"
    "kid" = $id
    "typ" = "JWT"
}| ConvertTo-Json) -PayloadJson (@{
    "exp" = ([DateTimeOffset](Get-date).AddMinutes(5)).ToUnixTimeSeconds()
    "iat" = ([DateTimeOffset](Get-date)).ToUnixTimeSeconds()
    "aud" = "/admin/"
} | ConvertTo-Json) -Secret $secretBytes

Invoke-RestMethod -Uri "https://scrumbug.ghost.io/ghost/api/admin/pages/$($trainingPage.id)" `
    -Method PUT `
    -Body ($pageJson | ConvertTo-Json) `
    -Headers @{Authorization="Ghost $jwtToken "}

For a more complete walkthrough, see my blog . 有关更完整的演练,请参阅我的博客

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM