0

0

Go语言中通过JWT授权Google服务账户的教程

DDD

DDD

发布时间:2025-10-02 14:35:01

|

775人浏览过

|

来源于php中文网

原创

Go语言中通过JWT授权Google服务账户的教程

本教程详细介绍了在Go语言中,如何利用JWT(JSON Web Token)机制授权Google服务账户。我们将逐步学习如何获取必要的Google服务账户凭据,特别是将P12私钥转换为PEM格式,并提供完整的Go代码示例,演示如何使用goauth2/oauth/jwt包来生成访问令牌,从而实现对Google服务的认证和访问。

1. 简介与前提条件

在使用go语言google服务进行交互时,服务账户(service account)提供了一种安全、无需用户参与的认证方式。通过jwt授权,我们可以使用服务账户的私钥直接生成访问令牌,进而调用google api。

在开始之前,请确保您具备以下条件:

  • 已安装Go语言开发环境。
  • 已拥有一个Google Cloud项目,并在其中创建了服务账户。
  • 已从Google Cloud Console下载了服务账户的P12私钥文件。
  • 已安装openssl工具,用于处理密钥文件。

2. 获取Go语言依赖库

首先,我们需要获取Go语言中用于OAuth2和JWT认证的库。本教程将使用code.google.com/p/goauth2包,它是Google官方早期提供的OAuth2客户端库。

在终端中执行以下命令:

go get code.google.com/p/goauth2/oauth

3. 准备Google服务账户凭据

3.1 获取服务账户信息

在Google Cloud Console中,导航到“IAM & Admin” -> “Service Accounts”。

立即学习go语言免费学习笔记(深入)”;

  • 服务账户电子邮件地址 (Service Email): 记录下您要使用的服务账户的电子邮件地址,例如your-service-account@your-project-id.iam.gserviceaccount.com。
  • P12私钥文件: 在创建服务账户时,您可以选择生成新的密钥并下载P12格式的私钥文件。请妥善保管此文件。

3.2 转换P12私钥为PEM格式

goauth2库在处理私钥时,需要的是PEM格式的未加密RSA私钥。您下载的P12文件是加密的且可能包含证书。我们需要使用openssl将其转换为PEM格式的纯RSA私钥。

假设您的P12文件名为file.p12,执行以下命令:

MCP Market
MCP Market

MCP Servers集合平台,帮你找到最好的MCP服务器

下载
openssl pkcs12 -in file.p12 -nocerts -out key.pem -nodes
  • -in file.p12: 指定输入的P12文件。
  • -nocerts: 排除证书,只输出私钥。
  • -out key.pem: 指定输出的PEM格式文件名为key.pem。
  • -nodes: 不对输出的私钥进行加密。

执行此命令后,openssl可能会要求您输入P12文件的密码(通常是notasecret,如果您在下载时没有指定)。成功后,key.pem文件将包含未加密的RSA私钥。请确保删除key.pem文件中可能存在的额外文本(例如,Bag Attributes或-----BEGIN/END CERTIFICATE-----之间的内容,只保留-----BEGIN RSA PRIVATE KEY-----和-----END RSA PRIVATE KEY-----之间的内容)。

4. 编写Go语言授权代码

现在,我们可以编写Go代码来使用这些凭据生成访问令牌。

package main

import (
    "code.google.com/p/goauth2/oauth/jwt" // 导入JWT包
    "flag"
    "fmt"
    "io/ioutil"
    "net/http" // 使用net/http代替旧的http包
)

var (
    serviceEmail = flag.String("service_email", "", "OAuth service email.")
    keyPath      = flag.String("key_path", "key.pem", "Path to unencrypted RSA private key file.")
    scope        = flag.String("scope", "", "Space separated scopes.")
)

// fetchToken 函数用于获取Google服务的访问令牌
func fetchToken() (string, error) {
    // 1. 读取PEM格式的私钥文件
    keyBytes, err := ioutil.ReadFile(*keyPath)
    if err != nil {
        return "", fmt.Errorf("无法读取私钥文件: %v", err)
    }

    // 2. 创建JWT令牌配置
    // 参数: 服务账户邮箱, 授权范围, 私钥字节
    t := jwt.NewToken(*serviceEmail, *scope, keyBytes)

    // 3. 创建HTTP客户端
    c := &http.Client{}

    // 4. 断言并获取访问令牌
    // t.Assert(c) 会向Google OAuth2服务器发送请求,交换JWT为OAuth2访问令牌
    o, err := t.Assert(c)
    if err != nil {
        return "", fmt.Errorf("无法获取访问令牌: %v", err)
    }

    return o.AccessToken, nil
}

func main() {
    flag.Parse() // 解析命令行参数

    if *serviceEmail == "" || *scope == "" {
        fmt.Println("错误: 必须指定服务账户邮箱和授权范围。")
        flag.PrintDefaults()
        return
    }

    token, err := fetchToken()
    if err != nil {
        fmt.Printf("错误: %v\n", err)
    } else {
        fmt.Printf("成功获取访问令牌: %v\n", token)
    }
}

代码说明:

  • import "code.google.com/p/goauth2/oauth/jwt": 导入了核心的JWT处理包。
  • flag 包: 用于从命令行接收服务账户邮箱、私钥路径和授权范围。
  • *`ioutil.ReadFile(keyPath)`**: 读取PEM格式的私钥文件内容。
  • jwt.NewToken(*serviceEmail, *scope, keyBytes): 创建一个jwt.Token实例。
    • *serviceEmail: 您的服务账户邮箱。
    • *scope: 授权范围,是一个空格分隔的字符串,指定了您的应用程序需要访问的Google API权限。例如,如果您需要访问Google Cloud Storage,范围可能是https://www.googleapis.com/auth/devstorage.full_control。请查阅相关Google API文档以获取正确的范围。
    • keyBytes: 读取到的PEM格式私钥的字节数组。
  • t.Assert(c): 这是核心步骤。它构建一个JWT,用私钥签名,然后将其发送到Google OAuth2服务器交换一个OAuth2访问令牌。
  • o.AccessToken: 成功后,o(类型为oauth.Token)将包含获取到的访问令牌。

5. 运行示例

将上述代码保存为main.go。在命令行中,使用以下方式运行:

go run main.go --service_email="your-service-account@your-project-id.iam.gserviceaccount.com" --key_path="key.pem" --scope="https://www.googleapis.com/auth/cloud-platform"

请将your-service-account@your-project-id.iam.gserviceaccount.com替换为您的服务账户邮箱,key.pem替换为您的私钥文件路径,并根据您的需求修改--scope参数。

如果一切顺利,您将看到控制台输出一个长字符串,即为成功获取的访问令牌。

6. 注意事项

  • 私钥安全: key.pem文件包含您的服务账户私钥,必须严格保密。不要将其上传到公共代码仓库或以不安全的方式传输。在生产环境中,考虑使用更安全的密钥管理方案。
  • 授权范围 (Scope): 选择最小必要的授权范围。过度授权会增加安全风险。仔细查阅您要使用的Google API的文档,了解所需的具体scope。
  • 令牌有效期: 获取到的访问令牌通常有较短的有效期(例如,1小时)。在令牌过期后,您需要重新执行上述流程以获取新的令牌。
  • 错误处理: 示例代码中包含了基本的错误处理,但在实际应用中,您应该实现更健壮的错误日志记录和重试机制。
  • 旧版库提示: code.google.com/p/goauth2是Go语言早期的一个OAuth2客户端库。虽然它仍然有效,但Go社区目前更推荐使用golang.org/x/oauth2及其相关的子包,它们提供了更现代、更灵活的API。然而,本教程严格遵循了原始问题中提供的解决方案。

7. 总结

本教程详细指导了如何在Go语言中使用JWT机制对Google服务账户进行授权。通过将P12私钥转换为PEM格式,并利用goauth2/oauth/jwt包,我们能够成功地获取访问令牌,为您的Go应用程序与Google服务的交互提供了坚实的认证基础。请务必注意私钥的安全性以及授权范围的合理配置,以确保您的应用程序安全可靠。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

180

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

228

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

340

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

209

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

393

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

197

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

191

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

233

2025.06.17

Golang 性能分析与pprof调优实战
Golang 性能分析与pprof调优实战

本专题系统讲解 Golang 应用的性能分析与调优方法,重点覆盖 pprof 的使用方式,包括 CPU、内存、阻塞与 goroutine 分析,火焰图解读,常见性能瓶颈定位思路,以及在真实项目中进行针对性优化的实践技巧。通过案例讲解,帮助开发者掌握 用数据驱动的方式持续提升 Go 程序性能与稳定性。

1

2026.01.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 8.4万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 3.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号