Skip to content

Instantly share code, notes, and snippets.

@kylebshr
Last active August 1, 2022 12:26
Show Gist options
  • Save kylebshr/0d295fe450c9c02289a26fcf0aca5b16 to your computer and use it in GitHub Desktop.
Save kylebshr/0d295fe450c9c02289a26fcf0aca5b16 to your computer and use it in GitHub Desktop.
Verifying a Sign in with Apple JWT in Vapor 3
/*
Once you've signed in with Apple in your iOS app, turn the `identityToken` into a string with something like
`String(data: identityToken, encoding: .utf8)`. Then use that string in the Authorization header:
`urlRequest.addValue("Bearer \(identityString)", forHTTPHeaderField: "Authorization")`
*/
import Vapor
import JWT
struct AppleJWT: JWTPayload {
let iss: IssuerClaim
let aud: AudienceClaim
let exp: ExpirationClaim
let iat: IssuedAtClaim
let sub: SubjectClaim
let c_hash: String
let email: String
let email_verified: String
let auth_time: Date
func verify(using signer: JWTSigner) throws {
try exp.verifyNotExpired()
}
}
struct User: Content {
var email: String
}
final class AuthenticationController {
func verifyAppleJWT(_ req: Request) throws -> Future<User> {
guard let bearer = req.http.headers.bearerAuthorization else {
throw Abort(.unauthorized)
}
return try req.client().get("https://appleid.apple.com/auth/keys").flatMap { response in
return try response.content.decode(JWKS.self).map { jwks in
let jwt = try JWT<AppleJWT>(from: bearer.token, verifiedUsing: JWTSigners(jwks: jwks))
return User(email: jwt.payload.email)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment