OAuth 2.0 和 JWT 在 Kotlin 中的授权:初学者完整指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

什么是 OAuth 2.0 和 JWT,为什么在 Kotlin 中需要它们?

\n\n

在现代 Web 开发中,数据安全和访问控制是关键任务之一。如果您用 Kotlin 编写服务器端应用程序,迟早会面临保护 API 或通过第三方服务(Google、GitHub、VK)实现登录的需求。为此,存在两个标准——OAuth 2.0(授权协议)和 JWT(JSON Web Token——令牌格式)。

\n\n

在本文中,我们将分析 OAuth 2.0 和 JWT 的工作原理,并使用流行的库在 Kotlin 中实现一个简单的授权。本材料面向初学者,因此所有复杂术语都将用通俗易懂的语言解释。

\n\n

基本概念:OAuth 2.0 和 JWT

\n\n

什么是 OAuth 2.0?

\n

OAuth 2.0 是一种协议,它允许一个服务(例如您的应用程序)在不传递登录名和密码的情况下,获得对用户在另一个服务(例如其在 Google 中的个人资料)上资源的有限访问权限。想象一下,您想通过 Google 帐户登录网站——这就是 OAuth 2.0。

\n\n

OAuth 2.0 的主要参与者:

\n
    \n
  • Resource Owner — 用户,数据所有者。
  • \n
  • Client — 您的应用程序,希望获得访问权限。
  • \n
  • Authorization Server — 颁发授权的服务器(例如 Google)。
  • \n
  • Resource Server — 存储用户数据的服务器(例如 Google API)。
  • \n
\n\n

什么是 JWT?

\n

JWT 是一种紧凑且自包含的令牌格式,包含有关用户的信息(例如 ID、角色、有效期)。令牌使用数字签名进行签名,因此无法伪造。JWT 由三部分组成,以点分隔:

\n\n
header.payload.signature
\n\n

解码后的 JWT 示例:

\n
{\n  "sub": "1234567890",\n  "name": "伊万·彼得罗夫",\n  "iat": 1516239022,\n  "exp": 1516242622\n}
\n\n

JWT 的主要优点是服务器无需在数据库中存储会话。所有信息都已包含在令牌内部。

\n\n

使用 Spring Boot 在 Kotlin 中实现 JWT 授权

\n\n

让我们看一个实际示例。我们将使用 Spring Boot 和 Spring Security 在 Kotlin 中创建一个 REST API。我们的应用程序将在成功身份验证后颁发 JWT 令牌。

\n\n

步骤 1. 添加依赖项

\n

将以下依赖项添加到 build.gradle.kts:

\n\n
dependencies {\n    implementation("org.springframework.boot:spring-boot-starter-security")\n    implementation("org.springframework.boot:spring-boot-starter-web")\n    implementation("io.jsonwebtoken:jjwt-api:0.12.5")\n    runtimeOnly("io.jsonwebtoken:jjwt-impl:0.12.5")\n    runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.12.5")\n}
\n\n

步骤 2. 创建 JWT 服务

\n

创建一个 JwtService 类,用于生成和验证令牌:

\n\n
import io.jsonwebtoken.Claims\nimport io.jsonwebtoken.Jwts\nimport io.jsonwebtoken.security.Keys\nimport org.springframework.stereotype.Service\nimport java.util.*\n\n@Service\nclass JwtService {\n    private val secretKey = "mySecretKeyForJwtToken12345678901234567890" // 至少 32 个字符\n    private val expirationMs = 3600000L // 1 小时\n\n    fun generateToken(username: String): String {\n        val claims: Map = mapOf(\n            "sub" to username,\n            "iat" to Date(),\n            "exp" to Date(System.currentTimeMillis() + expirationMs)\n        )\n        return Jwts.builder()\n            .claims(claims)\n            .signWith(Keys.hmacShaKeyFor(secretKey.toByteArray()))\n            .compact()\n    }\n\n    fun extractUsername(token: String): String? {\n        return try {\n            val claims = parseToken(token)\n            claims.subject\n        } catch (e: Exception) {\n            nul                

博客

书籍推荐