I have a problem with one request POST in ios using swift ...
In curl i send one request like this:
curl -H "Authorization: token ce2800d53d520b4a73a005a611d53d299e0c1d5e"....
and me server response with 200
However en ios i make me request like this:
let parametersH = [
"Authorization": "token 9640e65f66429415fb9359739ed8bc3f57cb0566"
]
Alamofire.request(Alamofire.Method.POST, "httpURL", parameters: parameters,headers:parametersH).progress { bytesWritten, totalBytesWritten, totalBytesExpectedToWrite in
}.responseJSON{ request, response, JSON, error in
if (error == nil) {
println(response)
}
else{
println(error)
}
}
But.....When i send the request for first time.....After install the application...The request....is correct and send one code 200 But... i close the application, and when in run again... i send the same request....(In this moments i hardcode the tokens and the url , for reason of test ) the server responds with un 403 .... I dont know what happened...why the first time work very good and the second not work... The token ...when i test this case is valid..
Hi @ErickB14,
Instead of creating a support issue in Github, please open a question on Stack Overflow and tag Alamofire. The Alamofire community is very helpful and supportive. Stack Overflow is the best place to get your question answered quickly and correctly.
Best of luck!
From our Contribution Guidelines
We don't use GitHub as a support forum. For any usage questions that are not specific to the project itself, please ask on Stack Overflow instead. By doing so, you'll be more likely to quickly solve your problem, and you'll allow anyone else with the same question to find the answer. This also allows maintainers to focus on improving the project for others.
I ran into this same problem and have been debugging for an entire day and finally figured it out. I'm almost positive the OP was using Django and I'm almost positive this has nothing to do with encoding: .URLEncodedInURL as it was referenced in a subsequent pull request.
I'm also going to post on his unanswered StackOverflow question, but I'm going to add a post here because I think some documentation needs to be appended to Alamofire so others don't run into this issue. It's a subtlety with either Alamofire or the underlying Swift/Objective C networking code. I _think_ if Alamofire receives a Set-Cookie in a response header, that it will send this information as a Cookie payload in subsequent request headers. This is different behaviour than other HTTP networking libraries, for example retrofit, which I never ran into this issue when developing my iOS app's Android counterpart.
As it pertains to Django, Alamofire will send the sessionid cookie value under the hood on subsequent requests, which makes Django think a session has been started and then you haven't provided the correct CSRF tokens and it'll throw a 403 permissions error.
To get around this problem, and in general to stop Alamofire from auto sending cookie values, set
let headers = [
"Cookie": ""
]
Please add this to the documentation if it isn't already. This burned an entire day of precious development time.
hi @gburlet I have the EXACT same issue. Server is in Django and my Alamofire response is always 403 for a subsequent request. I can't seem to wrap my head around it. Added the empty "Cookie" parameter to my header but it doesn't seem to work. Is there anything else you did?
Here's one of my simple API calls using POST. Client side and server side. Hopefully you can compare with your code and see a difference. Mine is working (Alamofire 4.5.1).
Swift:
/*
* Increment views total for an instrument transcription
* fretserv/viewinstrumenttranscription/
*/
static func viewInstrumentTranscription(_ itID:Int, callback: @escaping (Bool, String?) -> Void) {
let url = apiRoot + "fretserv/viewinstrumenttranscription/"
var headers = [
"Cookie": ""
]
headers = FretservAPI.finalizeHeaders(headers)
let parameters = [
"instrument_transcription": itID
]
NetworkManager.sharedInstance.defaultManager.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers)
.validate()
.responseJSON { response in
switch response.result {
case .success:
callback(true, nil)
case .failure:
if response.response?.statusCode != nil {
callback(false, generalError)
} else {
callback(false, serversDown)
}
}
}
}
The finalizeHeaders function just adds in a user agent string so shouldn't affect anything.
Django Rest Framework View:
# Increment the number of views for an instrument transcription
class ViewInstrumentTranscription(APIView):
def post(self, request):
try:
try:
it = InstrumentTranscription.objects.get(pk=request.data['instrument_transcription'])
except ObjectDoesNotExist:
return bad_request(request)
it.transcribed_sheet_music.views += 1
it.transcribed_sheet_music.save()
return Response({'msg': 'success'}, status.HTTP_200_OK)
except:
ErrorLogger.log(request.user_agent, reverse('increment_it_views'))
return Response(
{'msg': 'Oh snap! Something went terribly wrong. We have been notified!'},
status.HTTP_500_INTERNAL_SERVER_ERROR
)
Relevant snippets from Django settings.py:
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django_user_agents.middleware.UserAgentMiddleware',
)
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
)
}
If you're on a dev server, make sure to set your ATS to allow sending requests to your local dev server if it isn't HTTPS.
Hope that helps!
Most helpful comment
I ran into this same problem and have been debugging for an entire day and finally figured it out. I'm almost positive the OP was using Django and I'm almost positive this has nothing to do with
encoding: .URLEncodedInURLas it was referenced in a subsequent pull request.I'm also going to post on his unanswered StackOverflow question, but I'm going to add a post here because I think some documentation needs to be appended to Alamofire so others don't run into this issue. It's a subtlety with either Alamofire or the underlying Swift/Objective C networking code. I _think_ if Alamofire receives a
Set-Cookiein a response header, that it will send this information as aCookiepayload in subsequent request headers. This is different behaviour than other HTTP networking libraries, for example retrofit, which I never ran into this issue when developing my iOS app's Android counterpart.As it pertains to Django, Alamofire will send the
sessionidcookie value under the hood on subsequent requests, which makes Django think a session has been started and then you haven't provided the correct CSRF tokens and it'll throw a 403 permissions error.To get around this problem, and in general to stop Alamofire from auto sending cookie values, set
Please add this to the documentation if it isn't already. This burned an entire day of precious development time.