Getting Started with JWT in Vapor
Yuriy Gudimov
iOS Developer | 3+ years | SwiftUI | UIKit | Combine | REST APIs | Vapor
When building web applications, secure and efficient authentication is critical. One of the most popular methods for stateless authentication today is JSON Web Tokens (JWTs). In this article, I’ll introduce JWTs, explain their role in Vapor applications, and walk you through a basic implementation.
This is the first in a series of articles where we’ll explore various features of the Vapor framework. Let’s dive in!
What is JWT?
JWT stands for JSON Web Token, an open standard (RFC 7519) used for securely transmitting information between two parties. A JWT consists of three parts:
1. Header: Specifies the algorithm and type of token.
2. Payload: Contains the claims (data).
3. Signature: Verifies the token’s integrity.
JWTs are widely used for authentication and authorization because they are compact, self-contained, and digitally signed. Once issued, a token can validate a user’s identity without querying the database repeatedly, making the process fast and scalable.
Adding JWT to Your Vapor Project
First, include the JWT module in your Vapor project by updating your Package.swift file:
// swift-tools-version:5.10
import PackageDescription
let package = Package(
name: "my-app",
dependencies: [
.package(url: "https://github.com/vapor/jwt.git", from: "5.0.0"),
],
targets: [
.target(
name: "App",
dependencies: [
.product(name: "JWT", package: "jwt")
]
),
]
)
Run swift package update to fetch the dependency.
Configuring JWT in Vapor
Once added, configure your Vapor app to handle JWTs. In your configure.swift, set up a signing key:
import JWT
await app.jwt.keys.add(hmac: "super-secret-key", digestAlgorithm: .sha256)
This adds an HMAC key for signing and verifying JWTs. Replace "super-secret-key" with a secure key stored in your environment variables or configuration files.
Creating and Signing a JWT
To issue a JWT, we need to define a payload—the data included in the token. In Vapor, payloads conform to the JWTPayload protocol. Here’s an example:
struct UserPayload: JWTPayload {
enum CodingKeys: String, CodingKey {
case subject = "sub"
case expiration = "exp"
case isAdmin = "admin"
}
var subject: SubjectClaim
var expiration: ExpirationClaim
var isAdmin: Bool
func verify(using algorithm: JWTAlgorithm) async throws {
try expiration.verifyNotExpired()
}
}
Now, let’s create a route that generates a signed JWT:
领英推荐
app.post("login") { req async throws -> [String: String] in
let payload = UserPayload(
subject: "user123",
expiration: .init(value: .distantFuture),
isAdmin: true
)
let token = try await req.jwt.sign(payload)
return ["token": token]
}
When a user logs in, they receive a signed token. Here’s what the response might look like:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyMTIzIiwiZXhwIjo2NDA5MjIxMTIwMCwiYWRtaW4iOnRydWV9.b21pcA2GhE5Vv3rcUx4Gv9..."
}
Verifying JWTs
When a client sends a request with a JWT, you can verify its authenticity and extract the payload. Vapor simplifies this with the verify method:
app.get("me") { req async throws -> UserPayload in
let payload = try await req.jwt.verify(as: UserPayload.self)
return payload
}
This route checks the Authorization header for a valid token. If the token is valid, the payload is returned. If not, a 401 Unauthorized error is thrown.
Why Use JWT in Vapor?
1. Stateless Authentication: No need to store session data on the server.
2. Scalability: Perfect for distributed systems and microservices.
3. Flexibility: Add custom claims like roles or permissions to your payload.
Final Thoughts
JWTs are a powerful tool for managing authentication and authorization in modern web applications. Vapor’s first-class support for JWTs through the JWTKit library makes it easy to implement secure and efficient authentication in your Swift projects.
In the next article, we’ll explore more advanced topics, such as integrating OAuth with JWT or managing token expiration. Stay tuned!
If you have any questions or want to share your experiences with JWT in Vapor, feel free to drop a comment below. Let’s build something great together! ??
DevSecOps / DeFi (in)security / BobrCRV Ambassador
3 周Great advice
Frontend Developer | Angular
1 个月Useful. I use JWT lib too, but for typescript in Nest of course :)
Tech Entrepreneur | Team Lead & Software Engineer | Author & Speaker | Follow for daily posts about Mindset, Personal Growth, and Leadership
1 个月Great article! JWT is a powerful tool for authentication in Vapor. The step-by-step guide will make it easy to secure your app. Looking forward to the details!
Tech Entrepreneur | Team Lead & Software Engineer | Author & Speaker | Follow for daily posts about Mindset, Personal Growth, and Leadership
1 个月Insightful
Frontend Developer @TechWings | React, TypeScript, JavaScript | Improving UX Through Scalable Solutions
1 个月Very informative