Last active
April 14, 2018 02:12
-
-
Save pedantix/3f4f28d9e5b6f09528c5231eaa42a2c4 to your computer and use it in GitHub Desktop.
# Snippets For how I hacked together
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import Vapor | |
import PostgreSQL | |
import Authentication | |
/// Called before your application initializes. | |
/// | |
/// [Learn More →](https://docs.vapor.codes/3.0/getting-started/structure/#configureswift) | |
public func configure( | |
_ config: inout Config, | |
_ env: inout Environment, | |
_ services: inout Services | |
) throws { | |
// ... | |
try services.register(AuthenticationProvider()) | |
// Configure the rest of your application here | |
services.register { (container) -> FacebookClient in | |
let client = try container.make(Client.self, for: FacebookClient.self) | |
return FacebookClient(client: client) | |
} | |
let jwtSecret = ProcessInfo.processInfo.environment["JWT_SECRET"] ?? "secret" | |
let jwtService = JWTService(secret: jwtSecret) | |
services.register(jwtService) | |
services.register(SecureUserMiddleware()) | |
// ... | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import JWT | |
import Vapor | |
final class JWTService: Service { | |
var signer: JWTSigner | |
init(secret: String) { | |
signer = JWTSigner.hs512(key: Data(secret.utf8)) | |
} | |
func signUserToToken(user: User) throws -> String { | |
var jwt = JWT(payload: UserPayload(userId: user.id ?? 0)) | |
let data = try signer.sign(&jwt) | |
return String(data: data, encoding: .utf8) ?? "" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Vapor | |
import JWT | |
final class SecureUserMiddleware: Middleware, Service { | |
func respond(to request: Request, chainingTo next: Responder) throws -> Future<Response> { | |
guard | |
let authorization: String = request.http.headers["Authorization"].first, | |
let bearer = authorization.split(separator: " ").first, | |
let token = authorization.split(separator: " ").last, | |
bearer == "Bearer" | |
else { | |
throw Abort(.unauthorized, reason: "No Authorization Header") | |
} | |
let jwtService: JWTService = try request.make() | |
let userPayload = try JWT<UserPayload>(from: String(token), verifiedUsing: jwtService.signer).payload | |
return try User | |
.find(userPayload.userId, on: request) | |
.flatMap(to: Response.self, { maybeUser in | |
guard let user = maybeUser else { throw Abort(.unauthorized) } | |
try request.authenticate(user) | |
_ = try request.requireAuthenticated(User.self) | |
return try next.respond(to: request) | |
}) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// UserPayload.swift | |
// App | |
// | |
// Created by Shaun Hubbard on 2/21/18. | |
// | |
import Foundation | |
import JWT | |
struct UserPayload: JWTPayload { | |
var userId: Int | |
var exp: ExpirationClaim | |
init(userId: Int) { | |
self.userId = userId | |
exp = ExpirationClaim(value: Date(timeInterval: TimeInterval(24 * 60 * 60), since: Date())) | |
} | |
func verify() throws { | |
try exp.verify() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment