You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vapor Token认证未授权:如何在Alamofire中获取Basic Auth Token?

问题解决:Vapor登录接口未授权 + Alamofire获取Token错误

一、先排查Vapor服务器端的问题

服务器执行let user = try req.auth.require(User.self)抛出未授权,大概率是登录路由的认证中间件配置错误,或者用户模型的认证逻辑存在问题:

    1. 确认登录路由已添加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())
    
    1. 检查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)
        }
    }
    
    1. 确认用户密码是哈希存储的
      创建用户时必须用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 22:55:39