如何在Moya中设置basic auth用户名和密码?
How to set basic auth username and password in Moya?
我已经从 UITextField
中检索到用户名和密码,现在我想为 Moya 使用基本身份验证执行的每个请求设置用户名和密码。
我该怎么做?
涵盖基本身份验证的文档是 here
这是您需要的部分
HTTP 身份验证是 HTTP 协议本身内置的 username/password 挑战。如果您需要使用 HTTP 身份验证,您可以在初始化您的提供程序时提供一个 CredentialsPlugin。
let provider = MoyaProvider<YourAPI>(plugins: [CredentialsPlugin { _ -> URLCredential? in
return URLCredential(user: "user", password: "passwd", persistence: .none)
}
])
这个具体示例展示了使用 HTTP 对每个请求进行身份验证,这通常不是必需的。这可能是个更好的主意:
let provider = MoyaProvider<YourAPI>(plugins: [CredentialsPlugin { target -> URLCredential? in
switch target {
case .targetThatNeedsAuthentication:
return URLCredential(user: "user", password: "passwd", persistence: .none)
default:
return nil
}
}
])
这个解决方案对我不起作用。
问题是 URLCredential
仅用于身份验证质询,而不用于预授权请求。因此,如果您的 API 需要使用 Base64 "username:password" 参数的授权 header,这将不起作用。关于它的工作原理似乎有很多困惑,请参阅 Alamofire.
上的类似问题
我通过以下方法解决了这个问题:
解决方案 1
lazy var provider: MoyaProvider<LoginService> = {
let endpointClosure = { (target: LoginService) -> Endpoint<LoginService> in
let defaultEndpoint = MoyaProvider.defaultEndpointMapping(for: target)
switch target {
case .login(let username, let password):
return defaultEndpoint.adding(newHTTPHeaderFields: ["Authorization": "Basic " + "\(username):\(password)".data(using: .nonLossyASCII)!.base64EncodedString(options: []))
}
}
return MoyaProvider(endpointClosure: endpointClosure)
}()
这是使用 Moya 插件方法的其他解决方案:
解决方案 2
class AuthProvider {
static let basicAuthPlugin: PluginType = AccessTokenPlugin(tokenClosure: { () -> String in
guard let loginData = String(format: "\("username"):\("password")").data(using: .utf8) else { return "" }
return loginData.base64EncodedString()
})
}
let AuthAPIProvider = MoyaProvider<AuthAPI>(plugins: [AuthProvider.basicAuthPlugin])
enum AuthAPI {
// ... methods
}
extension AuthAPI: AccessTokenAuthorizable {
var authorizationType: AuthorizationType {
return .basic
}
}
我已经从 UITextField
中检索到用户名和密码,现在我想为 Moya 使用基本身份验证执行的每个请求设置用户名和密码。
我该怎么做?
涵盖基本身份验证的文档是 here
这是您需要的部分
HTTP 身份验证是 HTTP 协议本身内置的 username/password 挑战。如果您需要使用 HTTP 身份验证,您可以在初始化您的提供程序时提供一个 CredentialsPlugin。
let provider = MoyaProvider<YourAPI>(plugins: [CredentialsPlugin { _ -> URLCredential? in
return URLCredential(user: "user", password: "passwd", persistence: .none)
}
])
这个具体示例展示了使用 HTTP 对每个请求进行身份验证,这通常不是必需的。这可能是个更好的主意:
let provider = MoyaProvider<YourAPI>(plugins: [CredentialsPlugin { target -> URLCredential? in
switch target {
case .targetThatNeedsAuthentication:
return URLCredential(user: "user", password: "passwd", persistence: .none)
default:
return nil
}
}
])
这个解决方案对我不起作用。
问题是 URLCredential
仅用于身份验证质询,而不用于预授权请求。因此,如果您的 API 需要使用 Base64 "username:password" 参数的授权 header,这将不起作用。关于它的工作原理似乎有很多困惑,请参阅 Alamofire.
我通过以下方法解决了这个问题:
解决方案 1
lazy var provider: MoyaProvider<LoginService> = {
let endpointClosure = { (target: LoginService) -> Endpoint<LoginService> in
let defaultEndpoint = MoyaProvider.defaultEndpointMapping(for: target)
switch target {
case .login(let username, let password):
return defaultEndpoint.adding(newHTTPHeaderFields: ["Authorization": "Basic " + "\(username):\(password)".data(using: .nonLossyASCII)!.base64EncodedString(options: []))
}
}
return MoyaProvider(endpointClosure: endpointClosure)
}()
这是使用 Moya 插件方法的其他解决方案:
解决方案 2
class AuthProvider {
static let basicAuthPlugin: PluginType = AccessTokenPlugin(tokenClosure: { () -> String in
guard let loginData = String(format: "\("username"):\("password")").data(using: .utf8) else { return "" }
return loginData.base64EncodedString()
})
}
let AuthAPIProvider = MoyaProvider<AuthAPI>(plugins: [AuthProvider.basicAuthPlugin])
enum AuthAPI {
// ... methods
}
extension AuthAPI: AccessTokenAuthorizable {
var authorizationType: AuthorizationType {
return .basic
}
}