Vapor 4 / Swift:中间件开发

问题描述 投票:3回答:1

我对Swift和Vapor完全陌生;

[我正在尝试开发一个授权中间件,该中间件从我的UserModel(Fluent模型对象)中调用,并且超出了必需的访问级别(int)和Path(字符串)和

  1. 确保用户通过身份验证,
  2. 检查UserModel.Accesslevel的实例是否=>传入的必需访问级别,如果没有,则将用户重定向到“路径”。

我已经尝试了几天,总是很亲近,但从来没有完全得到我想要的。

我有以下内容(请不好称的对象):

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'过程中进行合并。

[我的另一种想法是检查用户是否已通过身份验证,如果可以,我可以放心地假设会话Cookie包含我的用户ID,因此我可以(再次)从数据库中拉出用户并从那里检查用户访问级别。] >

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

欢呼声

我对Swift和Vapor完全陌生;我正在尝试开发一个从我的UserModel(流体模型对象)调用的授权中间件,并且该中间件已超出必需的访问级别(int)和路径(...

swift middleware vapor vapor-fluent
1个回答
2
投票

[我使用使我的User模型符合ModelAuthenticatable的Vapor 4方法:

© www.soinside.com 2019 - 2024. All rights reserved.