Vapor Token认证未授权:如何在Alamofire中获取Basic Auth Token?
问题解决:Vapor登录接口未授权 + Alamofire获取Token错误
一、先排查Vapor服务器端的问题
服务器执行let user = try req.auth.require(User.self)抛出未授权,大概率是登录路由的认证中间件配置错误,或者用户模型的认证逻辑存在问题:
- 确认登录路由已添加Basic认证中间件
登录路由必须挂载User.authenticator()(前提是User实现了BasicAuthenticatable协议),示例代码:
app.post("login") { req -> Token in let user = try req.auth.require(User.self) let token = try Token.generate(for: user) try token.save(on: req.db).wait() return token } // 关键:添加该中间件才能解析Basic Auth凭证,将用户实例存入req.auth .middleware(User.authenticator())- 确认登录路由已添加Basic认证中间件
- 检查User类的
BasicAuthenticatable实现
确保协议实现正确,且密码验证逻辑无误(比如用BCrypt对比哈希值):
extension User: BasicAuthenticatable { static let usernameKey = \User.$email // 替换为你的用户名字段,如username static let passwordHashKey = \User.$passwordHash func verify(password: String) throws -> Bool { try Bcrypt.verify(password, created: self.passwordHash) } }- 检查User类的
- 确认用户密码是哈希存储的
创建用户时必须用BCrypt哈希密码,禁止存储明文:
let passwordHash = try Bcrypt.hash("user-password") let user = User(email: "user@example.com", passwordHash: passwordHash)- 确认用户密码是哈希存储的
二、Alamofire正确获取Token的方法
你返回用户列表是因为请求了错误的路由/HTTP方法(比如GET /users),登录接口应为POST请求,且需携带Basic Auth凭证:
正确的Alamofire请求示例
import Alamofire // 替换为你的实际登录接口地址 let loginURL = "http://localhost:8080/login" let username = "user@example.com" let password = "user-password" // 发送POST请求并携带Basic Auth AF.request(loginURL, method: .post) .authenticate(username: username, password: password) .responseDecodable(of: Token.self) { response in switch response.result { case .success(let token): print("Token获取成功:\(token.value)") // 此处可保存Token用于后续接口请求 case .failure(let error): print("登录失败:\(error.localizedDescription)") } }
注意事项
- 必须使用POST方法,Vapor默认CRUD路由中GET /users是获取用户列表接口,并非登录接口
authenticate(username:password:)会自动构造Authorization: Basic <base64编码的用户名密码>请求头,无需手动处理- 需定义与Vapor后端一致的
Token结构用于解析响应:struct Token: Codable { let id: UUID? let value: String let userId: UUID let createdAt: Date? }
内容的提问来源于stack exchange,提问作者Ramy Al Zuhouri
相关产品推荐
相关产品推荐

