401禁止使用Swift和邮枪发送电子邮件

401禁止使用Swift和邮枪发送电子邮件,swift,mailgun,Swift,Mailgun,我有以下代码,但在尝试运行它时始终得到错误401禁止: func email() { let session = URLSession.shared let request = NSMutableURLRequest(url: NSURL(string: "https://api.mailgun.net/v3/{edited_out}/messages")! as URL) request.httpMethod = "POST" let data = "from:

我有以下代码,但在尝试运行它时始终得到错误401禁止:

func email() {
    let session = URLSession.shared
    let request = NSMutableURLRequest(url: NSURL(string: "https://api.mailgun.net/v3/{edited_out}/messages")! as URL)
    request.httpMethod = "POST"
    let data = "from: Swift Email <(test@test.com)>&to: [my_email_address@gmail.com,(my_email_address@gmail.com)]&subject:Hello&text:Testing_some_Mailgun_awesomness"
    request.httpBody = data.data(using: String.Encoding.ascii)
    request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
    request.setValue("key-{edited_out}", forHTTPHeaderField: "api")
    let task = session.dataTask(with: request as URLRequest, completionHandler: {(data, response, error) in
        if let error = error {
            print(error)
        }
        if let response = response {
            print("url = \(response.url!)")
            print("response = \(response)")
            let httpResponse = response as! HTTPURLResponse
            print("response code = \(httpResponse.statusCode)")
        }
    })
    task.resume()
}
func电子邮件(){
让session=URLSession.shared
let request=NSMutableURLRequest(url:NSURL(字符串:)https://api.mailgun.net/v3/{edited_out}/messages“!作为URL)
request.httpMethod=“POST”
let data=“from:Swift Email&to:[我的电子邮件_address@gmail.com,(我的电子邮件_address@gmail.com)]&主题:你好&文本:测试“一些邮件”
request.httpBody=data.data(使用:String.Encoding.ascii)
request.setValue(“application/x-www-form-urlencoded;charset=utf-8”,用于httpheaderfield:“内容类型”)
setValue(“key-{edited_out}”,用于httpheaderfield:“api”)
让task=session.dataTask(其中:request作为URLRequest,completionHandler:{(数据,响应,错误)在
如果let error=error{
打印(错误)
}
如果让响应=响应{
打印(“url=\(response.url!)”)
打印(“响应=\(响应)”)
让httpResponse=响应为!HTTPURLResponse
打印(“响应代码=\(httpResponse.statusCode)”)
}
})
task.resume()
}
错误是:

    url = https://api.mailgun.net/v3/{edited_out}/messages
response = <NSHTTPURLResponse: 0x600000226a20> { URL: https://api.mailgun.net/v3/{edited_out}/messages } { status code: 401, headers {
    Connection = "keep-alive";
    "Content-Length" = 9;
    "Content-Type" = "text/html; charset=utf-8";
    Date = "Thu, 29 Dec 2016 21:22:46 GMT";
    Server = nginx;
    "Www-Authenticate" = "Basic realm=\"MG API\"";
} }
response code = 401
url=https://api.mailgun.net/v3/{edited_out}/消息
响应={URL:https://api.mailgun.net/v3/{edited_out}/messages}{状态代码:401,标题{
连接=“保持活动”;
“内容长度”=9;
“内容类型”=“文本/html;字符集=utf-8”;
日期=“2016年12月29日星期四21:22:46 GMT”;
服务器=nginx;
“Www-Authenticate”=“基本领域”=“MG API\”;
} }
响应代码=401
如果我用我的凭证通过curl发送这样的请求,它就可以正常工作


有什么想法吗?

您需要设置uesrname和密码

大概是这样的:

request.setValue("Basic \(base64Credentials)", forHTTPHeaderField: "Authorization")
base64凭据
是:

let credentials= String(format: "%@:%@", username, password)
let base64Credentials= credentials.data(using: String.Encoding.utf8)!

如果它对其他人有帮助,最终可以使用以下代码:

func email() {
    let session = URLSession.shared
    let request = NSMutableURLRequest(url: NSURL(string: "https://api.mailgun.net/v3/{edited_out}/messages")! as URL)

    request.httpMethod = "POST"
    let credentials = "api:key-{omitted}"
    request.setValue("Basic \(credentials.toBase64())", forHTTPHeaderField: "Authorization")

    let data = "from: Swift Email <(test@test.com)>&to: [my_email_address@gmail.com,(my_email_address@gmail.com)]&subject:Hello&text:Testing_some_Mailgun_awesomness"
    request.httpBody = data.data(using: String.Encoding.ascii)

    let task = session.dataTask(with: request as URLRequest, completionHandler: {(data, response, error) in
        if let error = error {
            print(error)
        }
        if let response = response {
            print("url = \(response.url!)")
            print("response = \(response)")
            let httpResponse = response as! HTTPURLResponse
            print("response code = \(httpResponse.statusCode)")
        }
    })
    task.resume()
}


extension String {

    func fromBase64() -> String? {
        guard let data = Data(base64Encoded: self) else {
            return nil
        }

        return String(data: data, encoding: .utf8)
    }

    func toBase64() -> String {
        return Data(self.utf8).base64EncodedString()
    }
}
而不是:

let base64Credentials = credentials.data(using: String.Encoding.utf8)!

这是身份验证错误,您应该传递正确的凭据我传递的是正确的详细信息。。它们可以通过curl正常工作。您可以显示正在使用的curl命令吗?错误表明您需要使用HTTP基本身份验证,即用户名和密码。您没有这样做。如何在CURL中传递凭据?CURL-s--user'api:key-{impleted}{impleted}/messages-F from='Excited user'-F to={impleted}@gmail.com-F subject='Hello'-F text='Testing'--(堆栈溢出正在将https://转换为链接)通常,您应该使用如下cURL传递凭据:
cURL-u username:password
cURL--user username:password
,所以我想说您的用户名是
api
,密码是
key blabla
,是这样吗?你确定你已经尝试过我的答案,在基本答案后面加空格吗?您已经将凭据解码到base64?是的,用户名api,密码密钥-XXXXXXX。我已经在上面添加了三行,并确保在单词Basic后面有一个空格。。。如果我打印(base64Credentials),它将显示为40字节,因此encoded@RJH这很奇怪,你能从你的浏览器中试试这个链接吗https://api:key-xxxxxx@api.mailgun.net/v3/samples.mailgun.org/log?你得到了什么?(您可能需要按域重播
samples.mailgun.org
,但我不确定,因此请尝试替换{省略}使用您的密钥当然可以。只要我更改密钥,身份验证部分就可以了。我得到了401。此代码仍然会为我抛出400个错误。我无法调试此问题。我准确地复制了代码,并将其替换为已验证的域名。此外,还添加了我自己的API密钥。
let base64Credentials = credentials.data(using: String.Encoding.utf8)!