You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ktor后端验证Google JWT Token

在Ktor后端验证Google ID Token的实现方案

1. 添加依赖

在项目构建文件中添加Ktor JWT验证及辅助解析依赖:

// build.gradle.kts示例
dependencies {
    implementation("io.ktor:ktor-server-auth-jwt:2.3.3") // 替换为你的Ktor版本
    implementation("com.auth0:java-jwt:4.4.0") // 辅助JWT解析
}

2. 配置JWT验证规则

在Ktor应用模块中配置认证插件,利用Google公钥自动验证Token签名:

import io.ktor.server.application.*
import io.ktor.server.auth.*
import io.ktor.server.auth.jwt.*

fun Application.configureGoogleJwtAuth() {
    install(Authentication) {
        jwt("google-auth") {
            // 加载Google公钥集,自动缓存更新
            verifier(
                JWTVerifier.create(
                    JWKS.load("https://www.googleapis.com/oauth2/v3/certs")
                )
                // 验证Token受众(你的Google OAuth客户端ID)
                .withAudience("YOUR_GOOGLE_CLIENT_ID")
                // 验证Token签发者(固定为Google账号服务)
                .withIssuer("https://accounts.google.com")
            )

            // 自定义验证逻辑,可额外检查业务字段
            validate { credential ->
                val userId = credential.payload.getClaim("sub").asString()
                val email = credential.payload.getClaim("email").asString()
                val isEmailVerified = credential.payload.getClaim("email_verified").asBoolean()

                // 根据业务需求添加验证条件
                if (userId.isNotEmpty() && email.isNotEmpty() && isEmailVerified) {
                    JWTPrincipal(credential.payload)
                } else {
                    null // 验证不通过返回null
                }
            }
        }
    }
}

3. 在路由中启用验证

将验证策略应用到需要保护的路由:

import io.ktor.server.routing.*
import io.ktor.server.auth.*
import io.ktor.server.response.*

fun Application.configureRoutes() {
    routing {
        // 应用Google JWT验证策略
        authenticate("google-auth") {
            post("/api/user/profile") {
                val principal = call.principal<JWTPrincipal>()
                val userInfo = mapOf(
                    "userId" to principal?.payload?.getClaim("sub")?.asString(),
                    "email" to principal?.payload?.getClaim("email")?.asString(),
                    "name" to principal?.payload?.getClaim("name")?.asString()
                )
                call.respond(userInfo)
            }
        }
    }
}

手动验证Token的备选方案

如果不需要集成Ktor Auth插件,可直接用java-jwt库手动验证:

import com.auth0.jwt.JWT
import com.auth0.jwt.algorithms.Algorithm
import com.auth0.jwt.interfaces.DecodedJWT
import java.security.interfaces.RSAPublicKey

fun verifyGoogleIdToken(token: String, clientId: String): DecodedJWT? {
    return try {
        val decodedToken = JWT.decode(token)
        val jwks = JWKS.load("https://www.googleapis.com/oauth2/v3/certs")
        val publicKey = jwks.getPublicKeyById(decodedToken.header.keyId) as RSAPublicKey

        val verifier = JWT.require(Algorithm.RSA256(publicKey, null))
            .withAudience(clientId)
            .withIssuer("https://accounts.google.com")
            .build()

        verifier.verify(token)
    } catch (e: Exception) {
        // 验证失败返回null,或根据需求处理异常
        null
    }
}

核心注意点

  • 客户端ID必须匹配:withAudience中的值要和Google Cloud Console创建的OAuth客户端ID完全一致,否则Token验证失败。
  • 签发者固定校验:Google ID Token的签发者始终是https://accounts.google.com,必须验证该字段防止伪造。
  • 公钥自动维护:JWKS.load会自动从Google端点获取最新公钥并缓存,无需手动更新。
  • 业务字段校验:可根据需求额外验证exp(过期时间)、email_verified等字段,提升安全性。

内容的提问来源于stack exchange,提问作者Fprogramer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 05:40:15