My need is to have a simple web form that also lets people upload some pdf's.
What I was thinking I could do (because of the size and number of uploaded files) is to tie the backend of this app to either my dropbox account or my box.com account.
Both services offer similar API's to build apps.
However they both assume I want to interact with people's dropbox/box account.
I think I kinda want the reverse of that. People would upload files to a web server but I want to upload them programatically to either of these 2 services, but under MY account with access and permissions related only to MY account.
The users don't need to interact with dropbox at all, they don't need to approve anything.
Why doesn't it seem possible to use the API in such a way that files can be added to the same, previously known, dropbox account which I own?
While this isn't the intended use, the basic idea would be to manually get an authorized access token for the account once, and save and reuse it for all future calls. (Just be sure not to revoke it.)
It is essentially the same way you would manage multiple users, except that each user just reuses the same access token, instead of their own.
I have had a similar issue using Facebook (FB) API in a few cases - where what I wanted was to have my server talk to FB in order to sync with my account - but the API is generally intended for use with the account of the person accessing the site.
The problem is that if you try to connect client-side, as the API is generally intended, you need to expose your own private log-in / credentialization via a client-side script... which clearly isn't good.
The trick I've used is to wrap the API server-side with a series of methods which allow you to perform the specific functions you need, then allow your JS or server-side binding to call those methods async. The resulting flowchart looks something like:
------ ---------- -------
| UI | -> AJAX -> | Server | -> Async GET w/Credentials -> | API |
------ ---------- -------
You then get the data back at the Server level and return it to the UI as JSON - and voila, your UI has no credentials - but still has access to your DropBox.
So - for your example of uploading a file... The user is going to post a file to your web-server. On the Server-side handler for the method - simply take the posted binary information, form it into a new API call to your drop-box - authenticate (if you don't already have an active authenticated session) - and then post. You can then return information to your client-side based on the success / failure of that call.
I hope this helps. :) Takes a bit of scaffolding - but it is possible! Have faith!
Related
When store owner installs my app I save access tokens into database for later use. Having access tokens from store is huge security responsibility because anybody with these tokens can modify stores from any domain/address, there is no ip or domain lock.
What method could I use to make this more secure? I was thinking to save tokens offline and then upload it only when needed (in case I need to make some global updates for all stores), then delete it again. In case when merchant access app configuration within admin, I would just save it into session. Is there any better method?
Good question.
I save them in a database as well but I encode them with a separate key from the Shopify App password. That way even if someone have access to the database because of some backdoor entrance he won't be able to use them. That said if someone have access to the code he will be able to figure out how to decrypt it since he will have access to the key.
That said I make sure that each and every request is authenticated before I show any response from the server. Since I'm using NodeJS as the back-end I make sure that there are no global variables that can be accessed or modified from different stores. Everything is neatly scoped in separated functions so that the session is scoped for the current store and no other ones will be able to dirty the other store session.
In addition I make sure that there is a webhook that fires when the client uninstall his app in order to clear my database from any information regrading his store.
I know some people are using sessions for this ( online method ) but they pose other problems that I didn't like so I stuck with a database ( offline ) since that is the quicker way to access the App instead of multiply redirects in order to save the session.
As for proposals I can give you a few tips that I learn on my way while building a few basic Apps. ( I'm not an expert on the subject by any means )
don't rely on any cookies when it comes to sensible information
authenticate every request that comes from the front-end
don't trust the user and validate any input that comes from the front-end
don't over-complicate your setup, while it's good to have high security it's bad if it makes your app slow for the user and you lose customers
look to other ready to use popular solutions that can guide you to the correct path
don't get greedy with the App scopes, only request the scopes that you need for you app
remember to clean up after yourself when it's possible but don't over do it ( too many Apps modify the code of customers and break it only to prevent any way to clean it afterwards ) Example use the ScriptTag API instead of a liquid snippet using the Asset API. If you have to use the Asset API add only the parts that you know that won't break a site. Creating a variable is ok if you are using var if the site supports IE11 creating a variable using const or let is not OK or using vanilla JS is OK but using jQuery without knowing for sure that the site has it installed globally is not OK.
More insights on the matter can be seen here:
https://help.shopify.com/en/api/getting-started/authentication/oauth/api-access-modes
https://community.shopify.com/c/Shopify-APIs-SDKs/Best-way-to-store-shops-that-have-installed-my-app-and-their/m-p/402972
I've been creating an extension for VSTS, and so far i have stored some data in documents in collections (https://learn.microsoft.com/en-us/vsts/extend/develop/data-storage).
The problem I have now, is that I need to GET these documents somehow from an external application. I have looked into: https://github.com/Microsoft/vsts-auth-samples/tree/master/ClientLibraryConsoleAppSample to get the authorization done, but then I am unable to get the documents. If I try to access through the REST API I have issues authorizing myself(without the personal access token provided. The application is supposed to work for every user, and i cannot get and use every user's personal access token. This is not feasible for 350+ people) as well as I am unable to get the REST API working. The documentation on all of this is severely lacking.
Anyone able to help?
The documentation is lacking, because the Data Storage is isolated for the extension and there is no easy way to access the data from outside of the extension. If you need external access, you also need to store your data externally. Azure storage or in a TFVC/Git repo under the VSTS account.
As for per-user storage access, that's also isolated and would indeed require either a account owner token or a user specific Oauth or PAT token.
I have found the solution. The documentation states that there are 2 ways of working with the documents/collections. REST API and their VSS wrappers. The url required to get all documents in a certain collection is as follows:
https://{account}.extmgmt.visualstudio.com/_apis/ExtensionManagement/InstalledExtensions/{publisherName}/{extensionName}/Data/Scopes/Default/Current/Collections/{collectionName}/Documents/{documentName}.
Using this in a browser works just fine. All that needs to be done in order to use this with an external application is authorization.
If you use sdk methods from docs like VSS.getService(VSS.ServiceIds.ExtensionData) you can view (easiest in dev tool in browser) the request.
Its look like:
https://extmgmt.dev.azure.com/{organization}/_apis/ExtensionManagement/InstalledExtensions/{publisher id}/{extension id}/Data/Scopes/Default/Current/Collections/{collections (by default 'MyCollection')}/Documents
I am new to REST APIs, I am actually not looking for any workarounds, I just need to clear my concept because I know I am missing some very important information which can easily solve my problem.
For E.g I made a small website, let's say using angular.js, where I will list some information or some items.
Consider it as an open website for now, everyone is getting same list. Anyone can come to the page and see the list of items. Simple.
Lets say the URL to this list is
https://www.example.com/api/list/v1
Result returned
1. abc
2. cde
3. efg
4. hij
Perfect!
Now my site got traffic, and I decided to implement user thing on my website, so that every user can only see his own information.
So I changed the rest api url to this:
https://www.example.com/api/list/v1/12345
where 12345 is userid.
The user with the user id came on the website, logged in, and browsed the list, by chance he went to the source of the page, and he found the url to list information.
He copied the url and started to use different user id's, he might get lucky any time.
I am not talking about implementing any type of security up til now, there must be several ways to secure it.
My main concern is that isn't it a large security hole, or we can call it an invitation, for injections?
So I just want to clear my understanding, where I am wrong?
Thanks
This is not some security loophole. This is the way it is supposed to work.
Let's put aside the case of APIs. Consider the simple example::
I have a url: www.example.com/jobs/
This will list all the jobs on my website. No authentication or permission of any sort is required to access this data. I am providing it to every user that visits my website. Now I need a way to figure out if the user visiting my website wants to filter the jobs available on my website. So I provide this option in url kwargs. This will look something like::
www.example.com/jobs/java/
So, now the list will contain the data only for Java jobs. Plain and simple.
Now some day I decide that I will let only the registered users to view Java Jobs. So, I introduce a new check in my View that lets you access the java jobs only if you are logged into my website. Otherwise it redirects you to the login page. Depending on the requirement, you put restrictions on the data being sent to the user.
Same is the case with APIs. If you allow the data to be available to any user that uses the API, there is a flaw with your design and not with the concept of APIs. APIs are just the implementation of your logic.
If you don't want a user with id 12345 to access the data of a user with id 123, you have got to restrict the permissions on the API code. You have got to handle themselves. The API will respond to your code.
Hope this clears out everything.
I know there are reports of various issues when trying to pull pictures posted by 'private' users. We are working on a project that we want to use the real-time api for. After a private user approves our account, we are able to view images posted by them through the api's as expected. In addition when searching by tag we see their images. The real-time API reports the image when we subscribe to the user endpoint. We want to subscribe to the tag api, the issue is that while everything else works with private users, for some reason when a private user posts an image with a tag for which our client has subscribed, the notification is not set. It is working fine for public users, and if we search (without real-time notification) we are able to see the image. The only thing I can think of is that for search to work we must use our access key for our account (not the posters), not our clientid, perhaps real-time needs to use the same security by accesskey rather than client id?
You are correct:
we must use our access key for our account (not the posters), not our clientid
Because the privacy permissions are per-account, if you are making authenticated API calls on behalf of the user, this will not work. In theory, if you kept your hourly API calls under the 5000 limit, you could technically proxy or cache the private photos, however, rather than looking at a complicated workaround, you're better to just adhere to the API ToU:
If your application has any cached copies of User Content that has become "private," you must remove such User Content as soon as reasonably possible.
The realtime API is a bit different than the regular API as well, in that while you may or may not receive a notification of a post (it's not the most reliable service), it does't contain any data, and you're still going out to fetch the relevant data using either your own access_token, your app client_id/secret, or an authenticated user token.
We have a large high traffic site with a lot of data on it (similar to Kickstarter), and we want to provide to our content/project creators a means of pulling their data from our site via an API.
Someone suggested I use OAuth, however my experience with OAuth is limited to setting up a twitter datasource.
What I want to do
Provide a user an Application ID and a 'secret'
Allow this user to connect to our application via an api endpoint, authorizing themselves using the api ID and secret
Once verified, allow this user to pull only their data from the application
The data that a user can pull: votes they have cast, pledges they have made, purchases they have made, projects/ideas they have launched, data about those projects/ideas (votes/purchases/orders/cancellations etc)
My question is:
Is OAuth overkill?
Is there a better way to handle a user/users website to connect to our API and pull/verify certain data by using the API we make available, while requiring each incoming request to be authorized for the user/site initiating that request.
Ideally, we will have an endpoint that is accessed as:
https://api.oursite.com/request/params
We want this to be as simple as possible for our users that wish to implement this interface. Thanks for your help!
Generally it's OAuth, in combination with SSL. That's the standard and is likely to stay. Before we saw also logins: username + password to access an API but that's becoming less and less.
So the suggested way is OAuth. There are no serious other solutions yet. To make it easier to adopt your API you could release some classes in some development languages so developers can have a quick start. You could start releasing those classes at for example GitHub to raise adoption of your API and get a quick access to developers. They might, if you do well, even start improving it.