gpt4 book ai didi

swift - Vapor 4/Swift : Middleware development

转载 作者:行者123 更新时间:2023-12-03 19:11:12 25 4
gpt4 key购买 nike

我对 Swift 和 Vapor 完全陌生;

我正在尝试开发一个从我的 UserModel(Fluent Model 对象)调用的授权中间件,并且在所需的访问级别(int)和路径(字符串)和

  • 确保用户通过身份验证,
  • 检查 UserModel.Accesslevel 的实例是否为 => Passed in Required Access 级别,如果不是,则将用户重定向到“路径”。

  • 我已经尝试了几天并且总是接近但从来没有完全得到我所追求的。

    我有以下内容(请原谅命名不佳的对象):
    import Vapor

    public protocol Authorizable: Authenticatable {
    associatedtype ProfileAccess: UserAuthorizable
    }

    /// status cached using `UserAuthorizable'
    public protocol UserAuthorizable: Authorizable {
    /// Session identifier type.
    associatedtype AccessLevel: LosslessStringConvertible

    /// Identifier identifier.
    var accessLevel: AccessLevel { get }
    }

    extension Authorizable {
    /// Basic middleware to redirect unauthenticated requests to the supplied path
    ///
    /// - parameters:
    /// - path: The path to redirect to if the request is not authenticated
    public static func authorizeMiddleware(levelrequired: Int, path: String) -> Middleware {
    return AuthorizeUserMiddleware<Self>(Self.self, levelrequired: levelrequired, path: path)
    }
    }

    // Helper for creating authorization middleware.
    ///
    //private final class AuthRedirectMiddleware<A>: Middleware
    //where A: Authenticatable
    final class AuthorizeUserMiddleware<A>: Middleware where A: Authorizable {
    let levelrequired: Int
    let path: String
    let authLevel : Int

    init(_ authorizableType: A.Type = A.self, levelrequired: Int, path: String) {
    self.levelrequired = levelrequired
    self.path = path
    }

    /// See Middleware.respond
    public func respond(to req: Request, chainingTo next: Responder) -> EventLoopFuture<Response> {
    if req.auth.has(A.self) {
    print("--------")
    print(path)
    print(levelrequired)
    **// print(A.ProfileAccess.AccessLevel) <- list line fails because the A.ProfileAccess.AccessLevel is a type not value**
    print("--------")
    }
    return next.respond(to: req)
    }
    }

    我在我的用户模型中添加了以下内容
    extension UserModel: Authorizable
    {
    typealias ProfileAccess = UserModel
    }

    extension UserModel: UserAuthorizable {
    typealias AccessLevel = Int
    var accessLevel: AccessLevel { self.userprofile! }
    }

    和这样的路线
        // setup the authentication process
    let session = app.routes.grouped([
    UserModelSessionAuthenticator(),
    UserModelCredentialsAuthenticator(),
    UserModel.authorizeMiddleware(levelrequired: 255, path: "/login"), // this will redirect the user when unauthenticted
    UserModel.authRedirectMiddleware(path: "/login"), // this will redirect the user when unauthenticted
    ])

    路径和所需级别正确传入,但我无法从当前用户获取 AccessLevel 的实例。 (我确定我戴着 C++ 帽子,并且从我可以“猜测”的内容来看,即使身份验证已经完成,UserModel 实际上并不是用户的填充实例)

    我尝试在使用关联类型传递帐户信息的“SessionAuthenticator”过程中进行合并。

    我的另一个想法是检查用户是否已通过身份验证,如果是,我可以安全地假设 session Cookie 包含我的用户 ID,因此我可以(再次)从数据库中提取用户并从那里检查用户访问级别。

    我可能会离开这里,几天后我不知道哪种方式是最好的方法,任何指导将不胜感激。

    干杯

    最佳答案

    我使用 Vapor 4 方法来符合我的 User型号到 ModelAuthenticatable :

    extension User:ModelAuthenticatable
    {
    static let usernameKey = \User.$email
    static let passwordHashKey = \User.$password

    func verify(password: String) throws -> Bool
    {
    try Bcrypt.verify(password, created:self.password)
    }
    }

    在我检查用户是否存在并且密码已按上述方式验证时,它会登录用户:
    request.auth.login(user)

    登录后,我使用自定义 Middleware检查用户是否登录和“ super 用户”,如果是,则响应传递给下一个 Middleware在链中,否则它会重定向到主页/登录页面,否则。
    struct SuperUserMiddleware:Middleware
    {
    func respond(to request:Request, chainingTo next:Responder) -> EventLoopFuture<Response>
    {
    do
    {
    let user = try request.auth.require(User.self)
    if user.superUser { return next.respond(to:request) }
    }
    catch {}
    let redirect = request.redirect(to:"UNPRIVILEGED")
    return request.eventLoop.makeSucceededFuture(redirect)
    }
    }

    我注册了 SuperUserMiddleware并与 configure.swift 中的某些路由组一起使用作为:
    app.middleware.use(SessionsMiddleware(session:MemorySessions(storage:MemorySessions.Storage())))
    app.middleware.use(User.sessionAuthenticator(.mysql))
    let superUserMW = SuperUserMiddleware()
    let userAuthSessionsMW = User.authenticator()
    let events = app.grouped("/events").grouped(userAuthSessionsMW, superUserMW)
    try EventRoutes(events)

    关于swift - Vapor 4/Swift : Middleware development,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62078573/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com