I have a backbone app (residing on mywebsite.proj.io) that takes code sends it to the django server (authorization.proj.io) that exchanges the code for an access token (simple oauth exchange). I am using Chrome/49.0.2623.87.
The authorization.proj.io sends a cookie back to the client (mywebsite.proj.io) during the auth stage, but this cookie never gets sent back again on future requests. I do not think it is a cross domain cookie issue or a browser unable to set a cookie on a 302 redirect.
I would like to know why the cookie is not be sent to the server on subsequent requests.
Here are some details:
Step 1: Request Header.. Authentication Phase Request: Sending the Oauth 'code' from mywebsite.proj.io to the authorization.proj.io to get the access token. This request is through ajax. The cookie you see here may be from a previous request, but do not care at this point really
GET /fbauth/?code=fb_code_long_string&state=%7B%22client_id%22%3A34343642979%2C%22network%22%3A%22facebook%22%2
Host: authorization.proj.io
Referer: http://mywebsite.proj.io/contribute/?code=fb_code_long_string&state=%7B%22client_id%22%3A34343642979%2C%22network%22%3
Cookie: csrftoken=1MTginTGXLHAku5LMHAMLLTrQEX2M4jj; sessionid=igc8a7vidgbi8rzxgm7whgb5rh8uqxa9`
Step 2: Response Header.. Authentication Phase Response [authorization.proj.io responds with 302 and gets redirected to mywebsite.proj.io and sets cookie]
HTTP/1.0 302 FOUND
Server: WSGIServer/0.1 Python/2.7.10
Vary: Cookie
X-Frame-Options: SAMEORIGIN
Location: http://mywebsite.proj.io/contribute/#access_token=CAAE
Set-Cookie: csrftoken=g0BEHLD0HAH4vBQLQFpKOEn2andrYMhG; expires=Tue, 14-Mar-2017 22:00:16 GMT; Max-Age=31449600; Path=/
Set-Cookie: sessionid=igc8a7vidgbi8rzxgm7whgb5rh8uqxa9; expires=Tue, 29-Mar-2016 22:00:16 GMT; httponly; Max-Age=1209600; Path=/
Step 3: Later, js from mywebsite.proj.io sends a requests to authorization.proj.io.. No cookie is sent
GET /posts/gcc-speaker-training-on-april-25 HTTP/1.1
Host: authorization.proj.io
Connection: keep-alive
Accept: application/json, text/javascript, */*; q=0.01
Origin: http://mywebsite.proj.io
Authorization: Basic facebook:CAAEdTwh7fCMBAMEr6wC3ajZANVnZBMPenjseiNShjcXOJJ0PbiJ0GFXI7lSjzkP
DNT: 1
Referer: http://mywebsite.proj.io/contribute/
There were a few things I had to do to get this working.
It turns out that I was doing cross domain requests, and here is how I solved it:
1 : Ensure the server serving your pages has the Access-Control-Allow-Origin set.. I was using the http-server and did the following:
`http-server . --cors`
2 : I did the following for the ajax call
$.ajax('http://authorization.proj.io', {
type: "GET",
contentType: "application/json; charset=utf-8",
success: function(data, status, xhr) {
// do something;
},
error: function(jqxhr, textStatus, errorThrown) {
console.log("cannot get orgs");
},
xhrFields: {
withCredentials: true
},
crossDomain: true
});
Note the xhrFields and crossDomain.
3: I did the following in django settings.py:
CORS_ORIGIN_ALLOW_ALL = False
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = (
'mywebsite.ngrok.io',
'authorization.proj.io'
)
SESSION_COOKIE_DOMAIN=".proj.com"
I think the last bit was important so that the browser can send the cookie.. So perhaps not cross domain, but cross sub-domain.
Related
I'm trying to authenticate against couchdb using this documentation
When I do
# first request
const url = 'http://localhost:5984/_session'
fetch(url, {
method: 'POST',
headers: {
"Content-Type": "application/json",
},
body : JSON.stringify({
"name": "my_username",
"password": "my_password"
}),
}).then( data => {
console.log(data)
}).catch(e => {
console.log('Error', e)
})
If one of my_username or my_password IS NOT right i get:
body: (...)
bodyUsed: false
headers: Headers {}
ok: false
redirected: false
status: 401
statusText: "Unauthorized"
type: "cors"
url: "http://localhost:5984/_session"
which is fine.
But, if one of my_username or my_password IS right i get:
body: ReadableStream
bodyUsed: false
headers: Headers {}
ok: true
redirected: false
status: 200
statusText: "OK"
type: "cors"
url: "http://localhost:5984/_session"
instead of
HTTP/1.1 200 OK
Cache-Control: must-revalidate
Content-Length: 43
Content-Type: application/json
Date: Mon, 03 Dec 2012 01:23:14 GMT
Server: CouchDB (Erlang/OTP)
Set-Cookie: AuthSession=cm9vdDo1MEJCRkYwMjq0LO0ylOIwShrgt8y-UkhI-c6BGw; Version=1; Path=/;
HttpOnly
{"ok":true,"name":"root","roles":["_admin"]} // <-- i expect that
And no cookie set.
I also tried curl, it works :
> curl http://localhost:5984/_session
{"ok":true,"userCtx":{"name":null,"roles":[]},"info":{"authentication_handlers":
["cookie","default"]}}
> curl -X POST http://localhost:5984/_session -H "Content-Type: application/json" -d '{"name":"my_username","password":"my_password"}'
{"ok":true,"name":"my_username","roles":["_admin"]}
But I need it to work in a react app, from http:localhost:3000
Maybe it's CORS related? I enabled CORS in CouchDB settings.
How can i modify the first request in order to get the user object for the name/password supplied?
I think Authentication Set-Cookie produce by backend server not by front end. So you need backend like Node.js to get cookie and then get it again from your front end.
I am making an ajax GET call currently from localhost:8090 with following:
$.ajax({
url: 'https://dev-855592.okta.com/api/v1/sessions/me',
method: 'GET',
dataType: 'json',
xhrFields: {
withCredentials: true
},
crossDomain: true,
success : function(data){
console.log(data);
},
error : function(data){
console.log('Session not found');
},
});
As this is an Okta call, it requires cookies to be sent with the request.
But IE 11 is not sending any cookies in the request.
I tried floowing things already:
"Access Data Sources Across Domains : Enabled" in ie11 settings in trusted sites. This solution is working.
But I don't want any impact on end-user and assuming end user has already accepted third party cookies, what should be the best way to achieve this?
If you want to enable CORS requests in IE 11, your server must attach the following headers to all responses:
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: ACL, CANCELUPLOAD, CHECKIN, CHECKOUT, COPY, DELETE, GET, HEAD, LOCK, MKCALENDAR, MKCOL, MOVE, OPTIONS, POST, PROPFIND, PROPPATCH, PUT, REPORT, SEARCH, UNCHECKOUT, UNLOCK, UPDATE, VERSION-CONTROL
Access-Control-Allow-Headers: Overwrite, Destination, Content-Type, Depth, User-Agent, Translate, Range, Content-Range, Timeout, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control, Location, Lock-Token, If
Access-Control-Expose-Headers: DAV, content-length, Allow
Optionally you can also attach the Access-Control-Max-Age header specifying the amount of seconds that the preflight request will be cached, this will reduce the amount of requests:
Access-Control-Max-Age: 3600
You could refer to this link about implementing CORS for a specific server.
I'm trying to submit a form from a react application, via post, to a django server on a different origin.
The browser sends an OPTIONS request, which the cors middleware on the server responds to with a 200, and the following information:
HTTP/1.1 200 OK
Date: Mon, 08 Apr 2019 16:34:38 GMT
Server: WSGIServer/0.2 CPython/3.7.2
Content-Type: text/html; charset=utf-8
Content-Length: 0
Vary: Origin
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: accept, accept-encoding, authorization, content-type, dnt, origin, user-agent, x-csrftoken, x-requested-with
Access-Control-Allow-Methods: DELETE, GET, OPTIONS, PATCH, POST, PUT
Access-Control-Max-Age: 86400
Connection: keep-alive
But the browser never subsequently makes a POST request. It shows no errors in the console...
Try to install django-cors-headers (https://pypi.org/project/django-cors-headers/) app and just add CORS_ORIGIN_ALLOW_ALL = True to you django settings file. It is the simplest way to fix you issue and this app gives you a lot of CORS customization options.
Or you can write custom middleware and add CORS headers for each response.
Otherwise you could add CORS headers config to you web-server (nginx, apache, etc.).
go to inspect element for request response, and check if any "headers are not allowed" message there.
If so, add that header to CORS_ALLOW_HEADER = ['that-header'] in django settings.py
In my case, cache-control header was not allowed. So I added it, it worked.
It turns out you have to add Cache-Control to CORS_ALLOW_HEADERS to get it to work correctly. Some browsers don't handle setting it to '*'. Here's my setup:
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_METHODS = [
"DELETE",
"GET",
"OPTIONS",
"PATCH",
"POST",
"PUT",
]
CORS_ALLOW_HEADERS = [
"accept",
"accept-encoding",
"authorization",
"content-type",
"dnt",
"origin",
"user-agent",
"x-csrftoken",
"x-requested-with",
"cache-control",
"pragma",
]
Every time i do a GET request to API from FrontEnd or POSTMAN to secured (isAuthenticated) content, i get 401 error(Unauthorized).
I have two servers:
1.Django, django-rest-framework, with Json Web Token.(API)
2.Vue.js
api endpoints:
Registration (AllowAny): http://holykrava.hopto.org:8002/user-api/register/
Login (AllowAny): http://holykrava.hopto.org:8002/user-api/get-token/
List of Users (IsAuthenticated): http://holykrava.hopto.org:8002/user-api/user-list/
Vue-Part
<script>
//import {HTTP} from './http-common';
import axios from 'axios'
export default {
created() {
//let tokenOld = localStorage.getItem('token')
let token = this.$store.state.token
axios.get(
'http://holykrava.hopto.org:8002/user-api/user-list/',
{headers: {
authorization: token
}}
)
.then(response => {
console.log(response);
})
.catch(error => {
console.log(error);
})
}
}
</script>
Chrome Dev Tool (Network-Logs)
General-Headers:
Request URL: http://holykrava.hopto.org:8002/user-api/user-list/
Request Method: GET
Status Code: 401 Unauthorized
Remote Address: 188.190.62.145:8002
Referrer Policy: no-referrer-when-downgrade
Request-Headers:
Provisional headers are shown
Accept: application/json, text/plain, */*
Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6Im11dGFwdXRhIiwiZXhwIjoxNTMxODUxODg0LCJlbWFpbCI6IiIsIm9yaWdfaWF0IjoxNTMxNzY1NDg0fQ.LGji_eCDVIvGpQ9xDEO2QAISEEW9FpHVcwRl6Oz9cCM
Origin: http://localhost:8080
Referer: http://localhost:8080/?
Response-Headers:
Access-Control-Allow-Origin: *
Allow: GET, HEAD, OPTIONS
Content-Length: 58
Content-Type: application/json
Date: Mon, 16 Jul 2018 19:34:45 GMT
Server: WSGIServer/0.2 CPython/3.6.4
Vary: Accept
WWW-Authenticate: JWT realm="api"
X-Frame-Options: SAMEORIGIN
IT Works in Terminal like this:
get token:
curl -X POST -d "username=userusername&password=userpassword" http://holykrava.hopto.org:8002/user-api/get-token/
pass token:
curl -H "Authorization: JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo0MCwidXNlcm5hbWUiOiJ1c2VydXNlcm5hbWUiLCJleHAiOjE1MzE4NDAxNTAsImVtYWlsIjoiIiwib3JpZ19pYXQiOjE1MzE3NTM3NTB9.SoITxagpmbviEFl_Iy086Jy0KgAUNV0WW-a3wMM_Fos" http://holykrava.hopto.org:8002/user-api/user-list/
corsheaders.middleware.CorsMiddleware, installed
CORS_ORIGIN_ALLOW_ALL = True
Default Authintication Class:
'rest_framework_jwt.authentication.JSONWebTokenAuthentication'
i spend two days trying to figure out whats wrong, but failed
looking for some1 who can help! thanks.
I am writing to Firebase Database from a Vapor server using the Firebase REST API. Why don't I get a Status code in the header received? This would enable me to check if the write was successful or not.
headerReceived items line 83 in
extensionPutRequestToUsersClaimBookingCleaner are
([Connection: "keep-alive", Cache-Control: "no-cache", Server:
"nginx", Date: "Sun, 27 Aug 2017 21:47:25 GMT", Content-Type:
"application/json; charset=utf-8", Content-Length: "1027",
Strict-Transport-Security: "max-age=31556926; includeSubDomains;
preload", Access-Control-Allow-Origin: "*"])
The response's status code is returned in the status property rather than the headers property.
guard response.status == .created else {
// not a 201 response
}