consume salesforce chatter rest service from pure javascript - javascript

I am creating a browser extension which posts to salesforce chatter using rest api.Once I get the access_token from OAuth user agent flow,I can not make call to rest services from javascript,due tobrowser same origin policy.I do not want to use a server as proxy,since I want to make the extension purely client side.
I tried JSONP workaround,but it only works for GET,I need POST to post a feed to salesforce chatter
is there a possible way.Please suggest some work around

Maybe consider passing your call to a custom rest service in salesforce. Setup a global class with the #RestResource annotation, and then within that an doPost method to handle what you're passing, in your case to make the post.
You'll still need the Oauth step to retrieve token that is then passed in with the rest request via the Authorization : Bearer header message.
See a good post on this here https://wiki.developerforce.com/page/Creating_REST_APIs_using_Apex_REST

Since Salesforce '15 you are able to configure CORS. Therefor whitelist your app domain and you can do whatever you want. Does not solve the problem to obtain an access_token. The only approach to obtain an access_token purely by javascript is to use the User-Agent Flow since the access Token is passed as URL Part....

One option is to use site like http://www.ajax-cross-domain.com/
Here is good reference on this matter http://www.d-mueller.de/blog/cross-domain-ajax-guide/

Use jsforce, you will need a proxy due to the CORS problem, sorry.

Related

ExpressJS - make route accessible only from internal redirect

I have an ExpressJS app with some routes that I don't want to work when typed into the url, they should work only when I redirect to them from my code.
Meaning, if an user types "myapp.com/url" it should not work. But if I add res.redirect("/url") in my code, it works
basically you can't prevent a client from sending an HTTP request to an endpoint (you can't make it "not work"). Having said that your requirements aren't that different from a login logic using JWT.
You can use JWT to set which endpoints the client can gain access to. If the client is not permitted you will redirect him to a different page.
See: https://github.com/auth0/express-jwt
Update (see comments):
when submitting the form you should generate a UUID for the request. This UUID will be a token that represents a temporary resource (video).
This is how the API will look more or less.
POST /submit
GET /generated/:UUID
GET /download/:UUID
You will need to implement some logic that will manage this temporary resource.
This is not possible as res.redirect (https://expressjs.com/en/4x/api.html#res.redirect) accept the routes which are already available via URL. If you don't want to publish the route to the outside world, you might do some sort of authorization before displaying or sending data.

How can I protect an HTTP POST request from only being received by an approved javascript client?

I have a URL that will accept POSTed data and store a record of it — this is for analytics. I need to secure that against anyone in the world from POSTing to it, but what possible authentication mechanism can I use that it is safe to expose the details of? I don't think the javascript can access any secret data without making it public.
I could base it off any HTTP header, but these can all be spoofed, right?
If it helps, both client and server are https.
Edit: I think I need to state the problem more explicitly; sorry, I thought I could explain it concisely, but it's clearly not coming across! Imagine the following:
A static page at https://example.com/index.html includes a script, https://example.com/script.js.
The script makes a request to another remote URL, e.g.
ajax_call('https://stats.example.com/stats.php', 'some data');
The stats.php script simply writes 'some data' to a file
Now, the flaw is that anyone can simply POST anything to stats.php and it will write to the file. I want to restrict that to just my 'client', i.e. https://example.com/index.html.
If I could, I would do something like this in stats.php:
if ($_SERVER["HTTP_REFERER"] == 'https://example.com') {
do_stuff();
} else {
die('not allowed');
}
but I've always been under the impression that HTTP_REFERER (and other similar headers) could just be spoofed, so that woud be pointless.
I need to secure that against anyone in the world from POSTing to it, but what possible authentication mechanism can I use that it is safe to expose the details of?
If the endpoint needs to be accessed by the browser of everybody who visits a public website, then you can't.
The browser is completely under the user's control. They can inspect everything the browser does. They can then recreate that using some other HTTP client.
If you trust the browser enough to let it make the request to your analytics API then you must trust the owner of the browser too. It is impossible to separate them.
The best you can do is analyse the data sent to the analytics API for usual or impossible patterns of behaviour.
You Can USE CORS and so enable your BackEnd to receive ONLY REQUEST from a specific HOST/DOMAIN

Get Request Workspace ID Asana Javascript

I'm trying to do a get request via javascript/jquery to attain all of my workspace IDs in asana. I know when I just put the URL in the browser, asana returns all of my workspace IDs. However, when I do a GET request of the same URL, I'm getting a 401 error (Not Authorized).
How do i fix this? I know after I do a login through OAuth I am provided a token, am I supposed to do something with that?
$.get("https://app.asana.com/api/1.0/workspaces", function(data){
alert("Data: " + data);
});
Also, please do not tell me to do it on the server side instead. I'm doing a simple web application and I'm doing it with javascript/jquery. That is not an answer. Thank you.
You need to authenticate your request, either using OAuth or the API Key. If you're developing an application for others to use, and you want them to be able to access their Asana data, you probably want to use OAuth - if it's just for a script you run for yourself, your API Key should be fine.
Generally speaking, OAuth has enough nuances that if you're using it (and not intimately familiar with it), we'd recommend using a library of some kind. If you're using jQuery, perhaps https://gist.github.com/andyedinborough/1012960 would help? (Caveat: I haven't tried it myself)
The short version of OAuth is that you need to get a token, which you can then pass to the API in the form of an HTTP header of the form Authorization: Bearer $TOKEN. It sounds like you already have a token, so you just need to add the header and it should work. And yet, GET is the correct verb to use here.

How to prevent direct access to my JSON service?

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.

Cross domain Ajax request from within js file

Here's the problem:
1.) We have page here... www.blah.com/mypage.html
2.) That page requests a js file www.foo.com like this...
<script type="text/javascript" src="http://www.foo.com/jsfile.js" />
3.) "jsfile.js" uses Prototype to make an Ajax request back to www.foo.com.
4.) The ajax request calls www.foo.com/blah.html. The callback function gets the html response and throws it into a div.
This doesn't seem to work though, I guess it is XSS. Is that correct?
If so, how can I solve this problem? Is there any other way to get my html from www.foo.com to www.blah.com on the client without using an iframe?
It is XSS and it is forbidden. You should really not do things that way.
If you really need to, make your AJAX code call the local code (PHP, ASP, whatever) on blah.com and make it behave like client and fetch whatever you need from foo.com and return that back to the client. If you use PHP, you can do this with fopen('www.foo.com/blah.html', 'r') and then reading the contents as if it was a regular file.
Of course, allow_remote_url_fopen (or whatever it is called exactly) needs to be enabled in your php.ini.
There is a w3c proposal for allowing sites to specify other sites which are allowed to make cross site queries to them. (Wikipedia might want to allow all request for articles, say, but google mail wouldn't want to allow requests - since this might allow any website open when you are logged into google mail to read your mail).
This might be available at some point in the future.
As mentioned above JSONP is a way around this. However, the site that you are requesting the data from needs to support JSONP in order for you to use on the client. (JSONP essentially injects a script tag into the page, and provides a callback function that should be called with the results)
If the site you are making a request to does not support JSONP you will have to proxy the request on your server. As mentioned above you can do this on your own server or what I have done in the past is use a http://www.jsonpit.com, which will proxy the request for you.
One option is to implement a proxy page which takes the needed url as a parameter. e.g. http://blah.com/proxy?uri=http://foo.com/actualRequest
JSONP was partially designed to get around the problem you are having
http://ajaxian.com/archives/jsonp-json-with-padding
JQuery has it in their $.getJSON method
http://docs.jquery.com/Ajax/jQuery.getJSON
The method shown above could become a large security hole.
Suggest you verify the site name against a white list and build the actual URI being proxied on the server side.
For cross domain hits this is a good working example and now is considered as some what "standard" http://www.xml.com/pub/a/2005/12/21/json-dynamic-script-tag.html.
there are other ways as well, for eg injecting iframes with document.domain altered
http://fettig.net/weblog/2005/11/28/how-to-make-xmlhttprequest-connections-to-another-server-in-your-domain/
I still agre that the easy way is calling a proxy in same domain but then it's not truly client side WS call.

Categories

Resources