I need to make something like google-analytics, I mean that it has to be very simple to install and enables a comunication between 2 websites.
Let me explain the idea.
I'm developping an application (with ZF) where my clients will be online shops, OSCommerce only at the begining. Those shops need to get some info from my app's database, send me some info and propose to their clients to use my app's service.
What does the code needs to do:
if there is a certain $_GET param in the URL (that indicates that the user is coming from my site) -> starts a session in the shop and send me some info for my stats (IP, browser info, etc...)
if this user buys something during this sesion -> send me some info about the sale (total, id, ...)
during the checkout process (checkout-payment.php in OSC) give the possibility to the user (the shop's client who is also a member of my application) to insert his email+password from his my-application's account in order to get a discount in the order he's placing.
I know how to program all this, editing the shop's files, but my problem is that I have no idea about how to make it in the google-analytics way (give a small javascript to my customers to install in their store) and neither what to look for in google in order to find the information I need.
So, can anyone helps me to get in the right path?
Thanks in advance
Since you'll be needing to go cross-domain with this utility, you'll want to write your javascript piece for inclusion using JSONP. Your JSONP "call" could simply be made to some PHP script on your server by tacking on information obtained from window.location (like the query string, for example).
Maybe all you need is to give your customer an URL pointing to your js library? And than your library can work or better provide them with API to your service to get customer data etc.?
And yes - JSONP can help you with inter-domain comunication...
Related
I need to be able to allow a customer (or group of customers in this case) to register for the store, and I need to be able to reference that group of customers in the code somehow, for example:
if (currentUserIdOfSomeSort === 9) {
// do something
} else {
// do something else
}
THE CATCH: I need to be able to accomplish this without the need for a person to go into BC and change a setting on the customer - if I have to go and assign the customer a specific group id, then that is not a solution because it involves human intervention.
Everything also needs to be local, as in I am not able to configure an external server to make API calls for specific information (for example, if I added a 'code' field to the registration form - I already asked, this will not create a new variable for that field, and I am told you would need to use a separate server to make the API call to return that info, something I do not know how to do)
Any ideas would be greatly appreciated
There is not a way to create your own custom global variables as these are functions of the core app. If you wanted to call to the API, you'd need to use Heroku (or your own server of choice) to make a request to the API. It can be a purely cURL request or you can use an API client.
curl --request GET \
-u "_username_:_API_key_"\
https://store.mybigcommerce.com/api/v2/customers/{id}.json
You can pass that into a js file hosted on the same server and then load the javascript on your storefront.
<script src="https://myserver.com/favoritenumber.js"></script>
You'd also need to do some validation that you were displaying this to the correct customer. I'd elect to use CustomerID instead of CustomerName and validate against this.
I would like to dynamically create a corresponding JSON file every time a new merchant signs up to my site.
For example:
Burger King signs up to be a merchant on my site. I add Burger king to my merchants.json file. How would I dynamically create a file that gets inserted into that JSON object that can later be used to pull up data specific to that merchant, on that merchants page. For example, a JSON file full of products or deals.
Is this even the right way to go about it?
Can someone point me in the right direction please?
This seems like a very common usage scenario but I don't see any examples online that explain this application structure thoroughly.
NOTE: I am using AngularJS
EDIT: Thanks for the tips guys, after asking around in the #AngularJS channel on IRC, I've been told to go the extra mile and create an API. I'll probably use sails.js to help with that. This obviously isn't how I was planning to do things, but as you guys pointed out, it wasn't the best practice; not by a long shot.
1) You'd need a small server-side PHP script that accepts the new JSON file sent by the client
2) Browser requests merchants.json from the server
3) Load it with JSON.parse()
4) Add the merchant to the Object
4) JSON.stringify(object)
5) Send back to the server.
Now, this is a horrible horrible idea. Use a server-side database for storing any kind of information on your clients -- MySQL, whatever. JSON is for transporting data, not storing it. You can write some PHP scripts to dynamically generate a page for your merchant based on the data in the database -- so much easier and so much more secure. The method above will expose the whole client database to the client, and based on your specifications above, I don't see another way.
Let's assume that I have created my REST service smoothly and I am returning json results.
I also implemented API key for my users to communicate for my service.
Then Company A started using my service and I gave them an API key.
Then they created an HttpHandler for bridge (I am not sure what is the term here) in order not to expose API key (I am also not sure it is the right way).
For example, lets assume that my service url is as follows :
www.myservice.com/service?apikey={key_comes_here}
Company A is using this service from client side like below :
www.companyA.com/services/service1.ashx
Then they start using it on the client side.
Company A protected the api key here. That's fine.
But there is another problem here. Somebody else can still grab www.companyA.com/services/service1.ashx url and starts using my service.
What is the way of preventing others from doing that?
For the record, I am using WCF Web API in order to create my REST services.
UPDATE :
Company A's HttpHandler (second link) only looks at the host header in order to see if it is coming from www.companyA.com or not. but in can be faked easily I guess.
UPDATE 2 :
Is there any known way of implementing a Token for the url. For example, lets say that www.companyA.com/services/service1.ashx will carry a querystring parameter representing a TOKEN in order for HttpHandler to check if the request is the right one.
But there are many things here to think about I guess.
You could always require the client to authenticate, using HTTP Basic Auth or some custom scheme. If your client requires the user to login, you can at least restrict the general public from obtaining the www.companyA.com/services/service1.ashx URL, since they will need to login to find out about it.
It gets harder if you are also trying to protect the URL from unintended use by people who legitimately have access to the official client. You could try changing the service password at regular intervals, and updating the client along with it. That way a refresh of the client in-browser would pull the new password, but anyone who built custom code would be out of date. Of course, a really determined user could just write code to rip the password from the client JS programmatically when it changes, but you would at least protect against casual infringers.
With regard to the URL token idea you mentioned in update 2, it could work something like this. Imagine every month, the www.companyA.com/services/service1.ashx URL requires a new token to work, e.g. www.companyA.com/services/service1.ashx?token=January. Once it's February, 'January' will stop working. The server will have to know to only accept current month, and client will have to know to send a token (determined at the time the client web page loads from the server in the browser)
(All pseudo-code since I don't know C# and which JS framework you will use)
Server-side code:
if (request.urlVars.token == Date.now.month) then
render "This is the real data: [2,5,3,5,3]"
else
render "401 Unauthorized"
Client code (dynamic version served by your service)
www.companyA.com/client/myajaxcode.js.asp
var dataUrl = 'www.companyA.com/services/service1.ashx?token=' + <%= Date.now.month %>
// below is JS code that does ajax call using dataUrl
...
So now we have service code that will only accept the current month as a token, and client code that when you refresh in the browser gets the latest token (set dynamically as current month). Since this scheme is really predictable and could be hacked, the remaining step is to salted hash the token so no one can guess what it is going to be .
if (request.urlVars.token == mySaltedHashMethod(Date.now.month)) then
and
var dataUrl = 'www.companyA.com/services/service1.ashx?token=' + <%= mySaltedHashMethod(Date.now.month) %>
Which would leave you with a URL like www.companyA.com/services/service1.ashx?token=gy4dc8dgf3f and would change tokens every month.
You would probably want to expire faster than every month as well, which you could do my using epoch hour instead of month.
I'd be interested to see if someone out there has solved this with some kind of encrypted client code!
What you're describing is generally referred to as a "proxy" -- companyA's public page is available to anyone, and behind the scenes, it makes the right calls to your system. It's not uncommon for applications to use proxies to get around security -- for example, the same-origin policy means that your javascript can't make Ajax calls to, say, Amazon -- but if you proxy it on your own system, you can get around this.
I can't really think of a technical way to prevent this; once they've pulled data from your service, they can use that data however they want. You have legal options, of course; you can make it a term of service that proxying isn't allowed, and pull their API key if they don't comply. But most likely, if you haven't already included that in the TOS, you'd have to wait for, say, a renewal of their subscription to your service.
Presumably if they're making server-side HTTP requests to your service, those requests are all coming from the same IP address, so you could block that address. You'd probably want to tell them first, and they could certainly get around that if they wanted to.
With the second link exposed by Company A I don't think you can do much. As I understand it, you can only check whether the incoming request comes from Company A or not.
But each request issued to www.companyA.com/.. can't be distinguished from original request from Company A. Everyone they let in uses their referrer as a disguise.
I have a JSON web service to return home markers to be displayed on my Google Map.
Essentially, http://example.com calls the web service to find out the location of all map markers to display like so:
http://example.com/json/?zipcode=12345
And it returns a JSON string such as:
{"address": "321 Main St, Mountain View, CA, USA", ...}
So on my index.html page, I take that JSON string and place the map markers.
However, what I don't want to have happen is people calling out to my JSON web service directly.
I only want http://example.com/index.html to be able to call my http://example.com/json/ web service ... and not some random dude calling the /json/ directly.
Quesiton: how do I prevent direct calling/access to my http://example.com/json/ web service?
UPDATE:
To give more clarity, http://example.com/index.html call http://example.com/json/?zipcode=12345 ... and the JSON service
- returns semi-sensitive data,
- returns a JSON array,
- responds to GET requests,
- the browser making the request has JavaScript enabled
Again, what I don't want to have happen is people simply look at my index.html source code and then call the JSON service directly.
There are a few good ways to authenticate clients.
By IP address. In Apache, use the Allow / Deny directives.
By HTTP auth: basic or digest. This is nice and standardized, and uses usernames/passwords to authenticate.
By cookie. You'll have to come up with the cookie.
By a custom HTTP header that you invent.
Edit:
I didn't catch at first that your web service is being called by client-side code. It is literally NOT POSSIBLE to prevent people from calling your web service directly, if you let client-side Javascript do it. Someone could just read the source code.
Some more specific answers here, but I'd like to make the following general point:
Anything done over AJAX is being loaded by the user's browser. You could make a hacker's life hard if you wanted to, but, ultimately, there is no way of stopping me from getting data that you already freely make available to me. Any service that is publicly available is publicly available, plain and simple.
If you are using Apache you can set allow/deny on locations.
http://www.apachesecurity.net/
or here is a link to the apache docs on the Deny directive
http://httpd.apache.org/docs/2.0/mod/mod_access.html#deny
EDITS (responding to the new info).
The Deny directive also works with environment variables. You can restrict access based on browser string (not really secure, but discourages casual browsing) which would still allow XHR calls.
I would suggest the best way to accomplish this is to have a token of some kind that validates the request is a 'good' request. You can do that with a cookie, a session store of some kind, or a parameter (or some combination).
What I would suggest for something like this is to generate a unique url for the service that expires after a short period of time. You could do something like this pretty easily with Memcache. This strategy could also be used to obfuscate the service url (which would not provide any actual security, but would raise the bar for someone wanting to make direct calls).
Lastly, you could also use public key crypto to do this, but that would be very heavy. You would need to generate a new pub/priv key pair for each request and return the pubkey to the js client (here is a link to an implementation in javascript) http://www.cs.pitt.edu/~kirk/cs1501/notes/rsademo/
You can add a random number as a flag to determine whether the request are coming from the page just sent:
1) When generates index.html, add a random number to the JSON request URL:
Old: http://example.com/json/?zipcode=12345
New: http://example.com/json/?zipcode=12345&f=234234234234234234
Add this number to the Session Context as well.
2) The client browser renders the index.html and request JSON data by the new URL.
3) Your server gets the json request and checks the flag number with Session Context. If matched, response data. Otherwise, return an error message.
4) Clear Session Context by the end of response, or timeout triggered.
Accept only POST requests to the JSON-yielding URL. That won't prevent determined people from getting to it, but it will prevent casual browsing.
I know this is old but for anyone getting here later this is the easiest way to do this. You need to protect the AJAX subpage with a password that you can set on the container page before calling the include.
The easiest way to do this is to require HTTPS on the AJAX call and pass a POST variable. HTTPS + POST ensures the password is always encrypted.
So on the AJAX/sub-page do something like
if ($_POST["access"] == "makeupapassword")
{
...
}
else
{
echo "You can't access this directly";
}
When you call the AJAX make sure to include the POST variable and password in your payload. Since it is in POST it will be encrypted, and since it is random (hopefully) nobody will be able to guess it.
If you want to include or require the PHP directly on another page, just set the POST variable to the password before including it.
$_POST["access"] = "makeupapassword";
require("path/to/the/ajax/file.php");
This is a lot better than maintaining a global variable, session variable, or cookie because some of those are persistent across page loads so you have to make sure to reset the state after checking so users can't get accidental access.
Also I think it is better than page headers because it can't be sniffed since it is secured by HHTPS.
You'll probably have to have some kind of cookie-based authentication. In addition, Ignacio has a good point about using POST. This can help prevent JSON hijacking if you have untrusted scripts running on your domain. However, I don't think using POST is strictly necessary unless the outermost JSON type is an array. In your example it is an object.
I'm debating the best way to propagate fairly complex permissions from the server to an AJAX application, and I'm not sure the best approach to take.
Essentially, I want my permissions to be defined so I can request a whole set of permissions in one shot, and adjust the UI as appropriate (the UI changes can be as low level as disabling certain context menu items). Of course, I still need to enforce the permissions server side.
So, I was wondering if anyone has any suggestions for the best way to
maintain the permissions and use them in server code
have easy access to the permissions in javascript
not have to make a round-trip request to the server for each individual permission
Thoughts?
If you have a clear set of permissions, like a "user level" or "user type", you could just pass the value down in a hidden field and access the value through the DOM. You could still do this if your permissions were more granular, but you would either have a lot of hidden fields or you would have to encode the information into XML or JSON or some other format.
You might set them as bit flags so that you could OR a single numeric value with a mask to see if the user had the permission for a specific activity. That would be very flexible and as long as you don't have more than 32 or so specific "rights", that would allow for any permutation of those rights in a very small package (basically an unsigned int).
For example:
0x00000001 //edit permission
0x00000002 //create new thing permission
0x00000004 //delete things permission
0x00000008 //view hidden things permission
.
.
.
0x80000000 //total control of the server and everyone logged in
Then a user with a permission of 0x000007 could edit, create, and delete, but nothing else.
In either case, I think you're on the right track - make the request once per page invocation, store the permissions in a global JavaScript data structure, and go from there. AJAX is nice, but you don't want to query the server for every specific permission all over your page. You would do it once on the page load, set up the presentation of your page and save the value in a global variable, then reference the permission(s) locally for event functions.
If you transmit the permission structure to the client as a JSON object (or XML, if you prefer), you can manipulate that object with the client-side code, and send it back to the server, which can do whatever it needs to validate the data and persist it.
I don't necessarily see it as the most "correct" solution, but would it be possible to keep all the permission stuff on the server side, and just serve the updated UI rather than some kind of JSON permissions system?
You'd have to make the decision based on how busy and intensive your app expects to be, but definitely a decision worth making either way
Encode them as JSON.