I have the following architecture for my app:
jQueryMobile web app --> Gets JSON from ---> REST API created in C#
I have placed the REST API Code in a virtual directory in IIS 6.
The Mobile site code is running in the root of the website... so the rough file structure is like this:
inetpub/
/index.html
myjavascript.js
/restapi/
web.config
Global.asax
bin/(bunch of Dlls...)
The Server is behind a network with the following sort of IP translation (not the real IPs...)
For example:
Web Server external IP: 121.131.141.50 (with URL http://mysite.com/)
Internal IP: 10.210.2.5
Subnet: 255.255.255.0
I have tried restricting access to the restapi folder by IP as I would like for it only to be accessible from the web server. I have tried the IIS approach and set Directory Security settings, and have also tried the approach of using a ServiceAuthorizationManager class to check Request IP in the Http Request.
Both approaches gave me the same result: There was no problem restricting and testing the actual service call through Fiddler to prove that a 401 would be thrown from any IP other than the web server IP: 10.210.2.5. I was also able to execute it from the webserver (which is the desired setup).
However, once the Mobile site javascript calls it, I get the 401 unauthorized. As the Javascript code is client side, the restapi assumes that the call is coming from the Client's IP address, which of course, is blocked.
Is there a neat way to check that the call comes from the IP where JavaScript is sitting?
Or Is there a better way to go about the whole thing?! :-/ Is there a way to make the web app specifically permitted to access the restapi virtual directory ?
Back to basics, your setup looks like this:
client <----> web server
HTTP
The web server hosts files which can be requested from outside by clients over the HTTP protocol. The web server is also where you filter incoming requests:
client <----> | web server
HTTP |
IP filter
If you say you want the REST service to be only accessible "on the same server", that means this:
client <----> web server
HTTP ^ |
| |
+----+
REST
But if the server is only talking to itself, you don't really need a full-blown REST interface to begin with. I guess what you actually mean is that the client, which downloads HTML and Javascript form the server, may request additional data from the server via REST.
client <----> web server
HTTP
<-------
HTML, JS files
-------->
AJAX
But as you see, the way it works is that the client downloads Javascript files from the server and executes that Javascript locally which then sends AJAX requests back to the server. The requests will always come from the client. They have to. It does not matter where the Javascript code that is making those requests originally came from. It could be a script from your server or it could be hand-typed by the user. An AJAX request is an HTTP request is an HTTP request like any other. Either you make your REST service accessible from outside or not, you cannot filter by the code that generated the request.
If you want to make the API non-public, require authentication so only registered users can access it. That doesn't make the API itself any less publicly accessible though.
Related
I recently learned about webhooks and am trying to implement one for a full-stack app that I'm building. However, I haven't been able to find information on how to create my own webhook. This is how my app is expected to work:
My client side is a website built with React, and when it loads, it will make a GET request to my server (built with Node and Express). The response will provide data that will be displayed on the website. The user will click a button on the website, which will send a (POST? GET?) request to my server, which will make its own POST request to send some of the data to an external API. When that external API data completes work on the data, it will send a POST request to my webhook URL (which I assume is part of my server), and the data from the external API needs to be sent to the client, which will display it alongside the original data. Additionally, when work on the first batch of data is completed, my server sends another POST request (with some more of the original data) to the external API, which will then make a POST request to my webhook/server with new data that then gets passed to the client again, and this repeats until all the original data from my server has been passed to and processed by the external API, and the all the processed data gets sent to my server and then to the client.
From my understanding, the webhook will allow my client to make a single request to my server, and then, my server can make multiple response to my client: one response for each POST request received from the external API. However, I have not been able to find information on how to create a webhook. Everything that I have found has been about how to use webhooks with pre-existing apps/websites like Dischord or GitHub or Stripe. Or using 3rd-party services to use their webhooks to connect pre-existing app/websites.
How do I go about making a webhook for my little project that will update my website every time that my server receives a POST request from the external API? Or am I misunderstanding how a webhook works? Can they only be created by 3rd-party services and/or only used on pre-existing apps?
For a simple use case, it just means another endpoint on your server that will receive a request from the external API when it's done with the task. It's a common way REST APIs work to let you know they are done with something, or communicate anything back to you in general. You have one endpoint that will receive a request from the React client, and send information off to the external API (as you said), and another endpoint (this "webhook") that will receive requests from the external API. That's it.
You described the client-server communications for this problem just fine with the exception that the server cannot send requests to the client over HTTP. If the client needs anything from the server, it needs to send a request and ask for it. A common way to do for this would be to store the information on the server once the external API hits your "webhook", and the client can ask the server if the data is back every X seconds (long-polling).
Example (payment flow):
Client -> Server: Heres my credit card number
Server -> Client: Thanks! Let me process that.
Server -> External API: Please process this credit card for the amount of $X and ping me at this webhook when you're done.
External API -> Server: OK, will let you know when I'm done.
Client -> Server: You done yet?
Server -> Client: Nope!
External API -> Server (to webhook): Hey, I'm done, here's the receipt.
Server -> External API: Thanks!
Client -> Server: You done yet?
Server -> Client: Yes! Here's your receipt.
More advanced ways to solve the problem would be using a long-lived bidirectional communication protocol such as websockets. And as others have mentioned, all of the endpoints don't have to be on the same server. You can have one server for each endpoint, and you can have turn them on only when they get a request and then go back to sleep (that's a Lambda). Pros and cons to this approach. That's more advanced stuff and if you're just learning I wouldn't really worry about it now.
AFAIK, webhooks are just normal web APIs. Properties that make an API a webhook:
The client sending requests to your server, in this case, is another server
This client will send you a request when there's a triggered event
In your case, your server POSTing data to the external API. What makes webhook different is that the external API's server doesn't have to respond right away, instead, it sends back you, for example, an HTTP 200 OK to acknowledge that it received the request and has started to process the data. When the external API's server finishes processing the data (which is an event), it will call your server's endpoint to inform you about the process along with the processed data (if succeeded).
Your server, correspondingly, will then have to inform your client (the user) about the processed data. I would suggest implementing some kinds of persistent connection (WebSocket or SSE), or simply just make the client poll request every some second.
"(which I assume is part of my server)"-- The webhook is part of the third party API that points back to either your server or maybe some serverless function/lambda(that you set up) that in turn can parse and perform computations on the data and then send it back to your server.
It really depends on the use case and architecture of your API. If you don't want your main API server to get overloaded, if say you need to perform heavy I/O, CPU/GPU processing, you could create Serverless Lambda Functions to handle this data processing and be the endpoint you supply to the third party's webhook post endpoint.
If you're not concerned with it, you could just create another endpoint in your server to handle this webhook.
Just keep in mind, when you're trying to scale up, you want your systems to be as distributed as possible-- within reason-- so your API can handle more requests and not be overloaded with a bunch of processes.
I am trying to develop a node app and require a server that can only be used by the app internally.
I have tried instantiating a server without listening to the port, but can't do anything with it from that point forwards:
let http = require("http");
http.createServer(function (req, res) {
// custom code
})
This app is being built with NWJS and I need to intercept any outgoing requests (including file resources; CSS, JS, images, etc.) and modify the response, but I am not having any success with it except if I use a server for this purpose.
Problem is it becomes possible to open that server on any browser and I just want it to be used only inside the app or another way to intercept outgoing requests from the app so that the response body can be modified.
I have tried Keith's suggestion of using a service worker to intercept requests, but in my case I could not load a service worker from local environment into live environment (for example, run a local sw file in stackoverflow page), so that suggestion ended there.
Stdob's suggestion of using a proxy ended up being redundant and more troublesome than my original attempt.
In the end I went with my original attempt as follows:
Using chrome.webRequest.onBeforeRequest (Chrome API) and a local node server.
The server is created with an arbitrary port to reduce the risk of hitting an already used port.
The chrome API redirects all connections to the local server (ex. url: http://127.0.0.1:5050) and then the server will handle the requests as needed, returning the requested files modified or intact.
Last step, add a unique header with a unique value that only the app knows, so that no server access can be made from outside the app.
It is not the best solution, ideally I would prefer to have something like Firefox's webRequest.filterResponseData, but until Chrome implements that, this will have to do.
I'm trying to figure out what is the "proper" way to make HTTP requests programatically from web application code when you don't know if you are or are not running behind reverse proxy (e.g. HTTPD).
Web application runs on root "/" context on web server
Proxy runs with context "/proxy" that proxies this that web server
Accessing index.html from browser should be requested via /proxy/index.html.
But what if there is some code in the web application (e.g. myscript.js) that sends HTTP request programatically (e.g. xhr.open("???/resource").
And here comes the problem because the code sends this HTTP request to /resource instead of sending it to /proxy/resource.
In other words, the code of web application (that runs in the browser) does not know if there is any or there isn't a proxy. Keep in mind that application can run behind proxy but there may not be any proxy at all. I have in mind 3 solutions:
1) Web application resolves context (e.g. /proxy) automatically by parsing it from the current window.location.path and send xhr according to it
2) Enhance web application to require some additional configuration of proxy from user and it appends the context if it is set
3) Configure proxy somehow to also resend non-proxy like URLs to web server 1:1 (e.g. /proxy -> webserver/, / -> webserver/)
Which one is "the proper" one or there are any other options?
Backend web applications should not be aware if there is proxy or not above or before them. They should ideally live in their own context path, eg. /application/ and if they need to send redirects do so without using hostnames or url schemes in it, just URL-Path /application/*
Then ideally you can do easy reverse proxy directives according to your number 3 scenario:
ProxyPass /XXX/ http://backend/application/
ProxyPassReverse /XXX/ http://backend/application/
I'm currently planning to develop a HTML5 app. The basic concept is the following:
A user should be able to create a profile with username and password. The Server should be implemented in Ruby on Rails providing a JSONP Api (for Cross-Domain issues).
So the App will send Ajax requests to the Server and get responses from it.
My idea was now to transmit a session_key (generated by server) on the first response back to the client. Then the client has to authenticate himself with this token.
But now i have some issues.
How can i secure the first call of the client (when he is transmitting user and password)?
How can i protect the Session-key from beeing spyed out?
I am a complety noob in security aspects. Therefore it would be great if i could get some hints where to look at.
Secure your connection with SSL. This should require no changes in your code apart from putting 's' after 'http' ;-).
I used add a checksum to the ajax parameters (calculated using the submitted data), and then to crypt the hole ajax request into one string.
Somthing like sRequest=459fdjnfdw4r908vn....
sRequests holds my data (sUser=user&sPass=pass&iCheck=34564).
Edit: My client code was not public, compiled to an app.
I have a client application in flash and a server application in C++ on linux. They communicate through a TCP socket and the server handles all of the game logic and communication between clients.
I'm now in the process of deploying my application onto a website. Embedding the swf is easy and working fine.
I want to be able to save statistical information about users and would like to use the Facebook login to uniquely identify users and store information about them in the mysql database.
I am now in a situation in which the javascript part of my server application (index.html using apache) needs to send the facebook information to the C++ part of my server (which contains all of the game logic and database management) so that I will know a users unique ID for the database.
Is it possible to send this information from Javascript to the C++ application?
You can make your C server act as a webserver, accepting connections following the HTTP protocol, and then you can send data with Ajax. Just remember to make your server send the Access-Control-Allow-Origin: yourdomain.com response header, replacing yourdomain.com with the domain you host the HTML+JS page on; this is to allow cross site requests, because the C server will be listening on another port than the webserver, and maybe another address too.