henrikac
(Henrik Christensen)
1
Hi 
I'm trying to make a middleware that checks if a request contains a valid apple jwt token + check if a user already exists with User.appleId == token.subject.value and create a new user if no user was found + make the token.subject.value available in my routes.
struct AppleSubjectKey: StorageKey {
typealias Value = String
}
extension Request {
var appleSubject: String? {
get {
self.storage[AppleSubjectKey.self]
}
set {
self.storage[AppleSubjectKey.self] = newValue
}
}
}
struct SignInWithAppleMiddleware: AsyncMiddleware {
func respond(to request: Request, chainingTo next: AsyncResponder) async throws -> Response {
guard let token = try? await request.jwt.apple.verify() else {
throw Abort(.unauthorized)
}
// check if user with appleId == token.subject.value
// create new user if no user was found
request.appleSubject = token.subject.value
return try await next.respond(to: request)
}
}
but while working on this middleware I read somewhere that using this approach the app would risk crashing if the server receive a lot of requests - is this true or would I be fine with this solution?
0xTim
(Tim)
2
@henrikac Storage is not thread safe (due to outdated assumptions about server implementations pre-concurrency. That's about to change but the number of requests shouldn't make a difference (where did you read that) since each request is isolated.
The thing you need to be careful of is writing the storage in multiple threads in a Swift concurrency world. However for your use case of write once in middleware, only read later you'll be fine
1 Like
henrikac
(Henrik Christensen)
3
Maybe I misunderstood the post that I read - it might have mentioned something about threads.
But to be sure: I should be fine setting e.g. request.appleSubject = token.subject.value in the middleware (+ searching for and potentially creating a user) and then read request.appleSubject in my routes?
0xTim
(Tim)
4
Correct yes, write in middleware read from anywhere after is fine
2 Likes
henrikac
(Henrik Christensen)
5
Cool.
Thank you for taking the time to answer my question 
Is there a "best answer" button?