我正在尝试使用GitHub应用程序,我需要生成一个JWT来进行身份验证(https://docs.github.com/en/developers/apps/building-github-apps/authenticating-with-github-apps#generating-a-私钥(我正试着用戈兰来做到这一点。如何在Go中从PEM私钥生成JWT??
jwt-go库拥有您需要的所有工具,并且有相当好的文档记录。你可以在https://github.com/golang-jwt/jwt.
假设您了解JWT是什么以及它们的结构,并且您可以将PEM密钥作为[]字节来获取,那么过程大致如下:
- 添加";github.com/golang jwt/jwt/v4";对您的进口产品
- 创建一组声明,其中可以包括RegisteredClaims类型和您可能需要的任何自定义声明
- 使用jwt创建令牌。NewWithClaims((-您需要提供适当的签名方法。我主要使用RS256
- 从带有token的token创建JWT字符串。SignedString((
在实践中,它看起来像这样:
imports "github.com/golang-jwt/jwt/v4"
type MyCustomClaims struct {
*jwt.RegisteredClaims
FooClaim int
BarClaim string
}
func CreateJWT(pemKey []byte) string {
// expires in 60 minutes
expiration := time.Now().Add(time.Second * 3600)
claims := MyCustomClaims{
RegisteredClaims: &jwt.RegisteredClaims{
Issuer: "Example Code Inc.",
ExpiresAt: jwt.NewNumericDate(expiration),
Subject: "JWT Creation",
},
FooClaim: 123,
BarClaim: "bar",
}
token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
privateKey, _ := jwt.ParseRSAPrivateKeyFromPEM(pemKey)
myJWT, _ := jwt.SignedString(privateKey)
return myJWT
}
要在Go中从私有权限文件成功创建github应用程序jwt令牌,需要以下jwt声明:
iat
:;在";令牌的日期(减去60秒的时钟浮动(exp
:令牌的到期日(自iat
起不超过10分钟iss
:Github应用程序的应用程序ID(注意:这不是应用程序的客户端ID(
一旦完成,就可以创建一个新的jwt令牌,用于与github api通信。
package main
import "github.com/golang-jwt/jwt/v5"
func main() {
pemFilePath := "private-key.pem" // replace
appId := "<app-id>" // replace
now := time.Now()
token := jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.MapClaims{
"iat": jwt.NewNumericDate(now.Add(-time.Minute)),
"exp": jwt.NewNumericDate(now.Add(5 * time.Minute)),
"iss": appID,
})
pemKey, _ := ioutil.ReadFile(pemFilePath)
privateKey, _ := jwt.ParseRSAPrivateKeyFromPEM(pemKey)
tokenString, err := token.SignedString(privateKey)
if err != nil {
panic(err)
}
fmt.Println(tokenString)
}
在上面的例子中,我们使用ioutil.ReadFile
读取pem文件的字节(这是由Github提供的(。然后解析字节,最后用它创建一个签名字符串。
注:
- 示例显示
exp
设置为5分钟。距离iat
不超过10分钟。最好从iat
值中选择.Add()
,以确保它是正确的时间 now.Add(-time.Minute)
基本上将当前时间减去一分钟
希望这能有所帮助。
我建议从这个存储库中读取代码:
https://github.com/bradleyfalzon/ghinstallation
我不知道为什么,但上面@JesseB的答案中的代码对我不起作用——它总是抛出:401未经授权。尽管此存储库在内部使用golang-jwt
包