Answered

Response for preflight is invalid - API

Name is required.
Email address is required.
Invalid email address
Answer is required.
Exceeding max length of 5KB

Akash Saggar

Nov 30, 2016 05:08AM CST

Hi guys,

I'm having trouble getting your API to work.
I'm trying to make a really super simple request to http://churchmetrics.com/api/v1/records.json
But I get an error saying "Response for preflight is invalid (redirect)".
When I googled this, it said that the server, (you guys), is not accepting OPTIONS requests.

I am not an expert at JavaScript, so it is probably my code that is wrong.

function request() {
xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = ProcessRequest;
xmlHttp.open( "GET", 'http://churchmetrics.com/api/v1/records.json', true );
xmlHttp.setRequestHeader('X-Auth-User', myEmail);
xmlHttp.setRequestHeader('X-Auth-Key', myAPI);
xmlHttp.send( null );
}

function ProcessRequest() {
if ( xmlHttp.readyState == 4 && xmlHttp.status == 200 ) {
console.log(xmlHttp.responseText);
}
}

I am really confused and have no idea what I am doing wrong, please help.
Thanks in advance!

Community Answers


Brandon L. Agent

Nov 30, 2016 05:52AM CST

Hello Akash,

Thanks for reaching out. I am going to loop in one of the Church Metrics pro, Juho.

Thank You,
Brandon

Up 1 rated Down

Juho Agent

Nov 30, 2016 09:29AM CST

Hi Akash,

Please try changing your API url to use https instead of http.

Did you see somewhere a URL for the API that’s not using https? If we have some documentation like that we’d like to get that updated.

Up -1 rated Down

Akash Saggar

Dec 02, 2016 11:53PM CST

Hey Juho,
No your documentation did not have http anywhere, I don't know why I used that haha...
Changing to https gives this error instead:
XMLHttpRequest cannot load https://churchmetrics.com/api/v1/records.json. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 404.

Through a bit of googling I found that this has something to do with Cross-Origin-Resource-Sharing (CORS), and that you can disable this (which should bypass the problem) through a Chrome extension called "Allow-Control-Allow-Origin: *"
https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi

When the extension is active, it instead gives this error:
XMLHttpRequest cannot load https://churchmetrics.com/api/v1/records.json. Response for preflight has invalid HTTP status code 404

Many Stack Overflow answers are saying it is a server side error. If you take a look at this link, it says you need to add something to the server side .htaccess file
http://stackoverflow.com/questions/33820142/getting-request-doesnt-pass-access-control-check-no-access-control-allow-orig

Thank you so much for your help

Up 0 rated Down

Juho Agent

Nov 30, 2016 10:37AM CST

Hi,

Could you first explain what you’re trying to achieve on the high level? Are you creating a website that other users will use, or is this just something that you want to have running on your own machine privately?

I wonder if you are trying to include your javascript (that calls the Church Metrics API) on some publicly accessible website? If yes, you would be including your API key in the javascript code, and anyone could get it from there. The API key allows also editing and deleting records, accessing users, etc., so I don’t recommend you to expose it in public like that.

You should typically call Church Metrics API on server side, and have the API key there so that it can’t be retrieved by anyone that doesn’t have direct access to the server. Then your own website backend can render or return the results for the website. This naturally fixes the CORS issue as well.

I wonder why you get 404, though. I might be able to help if you share your current code.

Blessings,
Juho

Up 0 rated Down

Akash Saggar

Dec 08, 2016 07:07PM CST

My Church wants me to integrate Church Metrics onto a page that will be hosted on our Church website. Basically this page has a lot of our Church's stats, and one of the few things missing is attendance (and possibly other info we record in Church Metrics), which I need to get through Church Metrics API.

I haven't thought about how to make the page/API keys secure yet. I know that the page would be password protected (only Pastors would know the password) using basic JavaScript, but as for the API keys, I will look into encryption or maybe server side method you mentioned. As of now it is just running on my local machine so I haven't added security.

Though I have tried hosting the page on the website just to test if that would make it work, but the results were the same, and then I took the page down.

As for my code, it is literally just what I have posted above. As I haven't been able to get the API to work yet, there is not code after this eg to display the retrieved data. Likely it would be in a table, but as for JavaScript code, that is it.
So you can think of it as a blank HTML page that will display Church attendance in a table. The only code is what I have posted above.

If you have an example, can you please post some basic code just to get something like attendance on a specific date?

Thanks for your help.

Up 0 rated Down

Juho Agent

Dec 03, 2016 04:39AM CST

Hi, as example code we have some in ruby here:
https://github.com/lifechurch/churchmetrics-api-examples

If you have problems accessing the API, could you first test with the curl example on command line that you can fetch records with your user & API key? See:
https://github.com/lifechurch/churchmetrics-api#making-a-request

I hesitate a bit to help you in preparing JavaScript for accessing the API, because I don’t see how it could be secured. So do you have a Node.js backend or how can you make authentication with JavaScript? Or do you have Basic Auth or something like that done by the web server, that is required to fetch any files of that website (including .js)?

If your JavaScript is made available in the public internet without authentication, there is no way you could call the Church Metrics API without exposing full access to anyone that can get their hands on that page.

Sorry for the delayed response.

Juho

Up 0 rated Down

Akash Saggar

Dec 21, 2016 10:23PM CST

Hi, I have never used curl before but managed to follow an example on how to use it in PHP. This is my code.

<?php
include 'ChromePhp.php';
$myEmail = 'email@example.com';
$myAPI = '12345';
$ch = curl_init('https://churchmetrics.com/api/v1/records.json');
$request_headers = array('X-Auth-User: '.$myEmail, 'X-Auth-Key: '.$myAPI);
curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
$response = curl_exec($ch);
curl_close($ch);
ChromePhp::log($response);
?>

ChromePhp is a chrome plugin that I used just so I could basically do a console.log() of the curl response. I don't know of a way to do this with the native chrome debugger and php, so I used the extension. It's called Chrome Logger on the store.

What it logs from the last line of code is just "false". It may be a boolean or a string, I'm not sure, but all I see in the debugger is false.

Sorry for the late replies as well, I don't get any sort of notification when you reply so I have to manually check whenever I remember.

I don't think we have a node js backend. I am completely unfamiliar with server side code. But, I have thought of something else.
I could create another database on phpmyadmin with the api key stored in it. When this web page that I am creating is accessed, it will ask the user to type in the password, which is the password it will use to try and access the database.
If the password is correct, and the database is accessed, the api key will be retrieved from there and will be used in the rest of the code.
This way, the api key will not actually be stored in the HTML file.

Thanks a lot

Up 0 rated Down

Juho Agent

Dec 10, 2016 01:55AM CST

Hi!

Actually what I meant is that you could try with cURL on command line (you can install if it you don’t have it yet). The example command is found in API documentation:

https://github.com/lifechurch/churchmetrics-api#making-a-request

If needed you can use some flags to see additional debug information with cURL (-v or —trace).

This would be just a test so that we can rule out that your problem in fetching data from the API is not about authentication or a bug in Church Metrics.

Cheers,
Juho

Up 0 rated Down

Akash Saggar

Jan 02, 2017 10:49PM CST

Hi!

Thanks for your help. I managed to get the API working through cURL in PHP so we can rule out that it is a bug in your system.

What I learned from this whole project, is that client side code such as JavaScript is subject to a same-origin policy that makes it so that GET/POST/etc requests can only be made from a file on one server to another file on the same server.
To do Cross Origin Resource Sharing, the file that is being queried must have an 'Access-Control-Allow-Origin' header in the response. If that header is set to an asterix (*), any website can make the request. If it is set to a specific url, such as maybe google.com, your API would only work if it was called from google.com.

The errors I was getting in JavaScript say "No 'Access-Control-Allow-Origin' header is present on the requested resource", so I think that is something you guys should add. It is preventing me from using JavaScript to access your API.

A really great and simple tutorial can be found on
https://www.html5rocks.com/en/tutorials/cors/

Server side code such as PHP is not subject to the same-origin restriction, so I will continue my project using PHP. Please work on adding CORS support to your API.

You were a great help, thank you so much for your time and effort.

Up 0 rated Down

Juho Agent

Dec 26, 2016 11:04PM CST

Great to hear that you found a solution!

I don’t think we’re wanting to allow arbitrary CORS with the current authentication model where there’s a fixed API key, because it could lead into implementing JavaScript websites without required consideration on security. What could work is adding OAuth support, so that each user could log in with their church metrics account to authorize API access. OAuth API would allow CORS “*” and check on the OAuth token for authorization. Unfortunately implementing OAuth would be a rather big feature to do. The way things are now, it’s best to use a server-side implementation when building anything on top of the API.

Thanks for the feedback and suggestions. It’s clear that the API doesn’t currently work for building light browser-side apps (securely), and we should consider improving that in a way or another.

Up 0 rated Down

Post Your Public Answer