Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to upload files to Box.com programmatically

I've read the whole Box.com developers api guide and spent hours on the web researching this particular question but I can't seem to find a definitive answer and I don't want to start creating a solution if I'm going down the wrong path. We have a production environment where as once we are finished working with files our production software system zips them up and saves them into a local server directory for archival purposes. This local path cannot be changed. My question is how can I programmatically upload these files to our Box.com account so we can archive these on the cloud? Everything I've read regarding this involves using OAuth2 to gain access to our account which I understand but it also requires the user to login. Since this is an internal process that is NOT exposed to outside users I want to be able to automate this otherwise it would not be feasable for us. I have no issues creating the programs to trigger everytime a new files gets saved all I need is to streamline the Box.com access.

like image 776
user1110938 Avatar asked Nov 27 '13 20:11

user1110938


2 Answers

I just went through the exact same set of questions and found out that currently you CANNOT bypass the OAuth process. However, their refresh token is now valid for 60 days which should make any custom setup a bit more sturdy. I still think, though, that having to use OAuth for an Enterprise setup is a very brittle implementation -- for the exact reason you stated: it's not feasible for some middleware application to have to rely on an OAuth authentication process.

My Solution:

Here's what I came up with. The following are the same steps as outlined in various box API docs and videos:

  1. use this URL https://www.box.com/api/oauth2/authorize?response_type=code&client_id=[YOUR_CLIENT_ID]&state=[box-generated_state_security_token] (go to https://developers.box.com/oauth/ to find the original one)
  2. paste that URL into the browser and GO
  3. authenticate and grant access
  4. grab the resulting URL: http://0.0.0.0/?state=[box-generated_state_security_token]&code=[SOME_CODE] and note the "code=" value.
  5. open POSTMAN or Fiddler (or some other HTTP sniffer) and enter the following:
    • URL: https://www.box.com/api/oauth2/token
    • create URL encoded post data:
      • grant_type=authorization_code
      • client_id=[YOUR CLIENT ID]
      • client_secret=[YOUR CLIENT SECRET]
      • code= < enter the code from step 4 >
  6. send the request and retrieve the resulting JSON data:
    {
    "access_token": "[YOUR SHINY NEW ACCESS TOKEN]",
    "expires_in": 4255,
    "restricted_to": [],
    "refresh_token": "[YOUR HELPFUL REFRESH TOKEN]",
    "token_type": "bearer"
    }
    

In my application I save both auth token and refresh token in a format where I can easily go and replace them if something goes awry down the road. Then, I check my authentication each time I call into the API. If I get an authorization exception back I refresh my token programmatically, which you can do! Using the BoxApi.V2 .NET SDK this happens like so:

var authenticator = new TokenProvider(_clientId, _clientSecret);
// calling the 'RefreshAccessToken' method in the SDK
var newAuthToken = authenticator.RefreshAccessToken([YOUR EXISTING REFRESH TOKEN]);
// write the new token back to my data store.
Save(newAuthToken);

Hope this helped!

like image 52
austriacus Avatar answered Sep 25 '22 06:09

austriacus


If I understand correctly you want the entire process to be automated so it would not require a user login (i.e run a script and the file is uploaded). Well, it is possible. I am a rookie developer so excuse me if I'm not using the correct terms.

Anyway, this can be accomplished by using cURL. First you need to define some variables, your user credentials (username and password), your client id and client secret given by Box (found in your app), your redirect URI and state (used for extra safety if I understand correctly).

The oAuth2.0 is a 4 step authentication process and you're going to need to go through each step individually.

The first step would be setting a curl instance:

curl_setopt_array($curl, array(

   CURLOPT_URL => "https://app.box.com/api/oauth2/authorize",

   CURLOPT_RETURNTRANSFER => true,

   CURLOPT_ENCODING => "content-type: application/x-www-form-urlencoded",

   CURLOPT_MAXREDIRS => 10,

   CURLOPT_TIMEOUT => 30,

   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,

   CURLOPT_CUSTOMREQUEST => "POST",

   CURLOPT_POSTFIELDS =>
 "response_type=code&client_id=".$CLIENT_ID."&state=".$STATE,

));

This will return an html text with a request token, you will need it for the next step so I would save the entire output to a variable and grep the tag with the request token (the tag has a "name" = "request_token" and a "value" which is the actual token).

Next step you will need to send another curl request to the same url, this time the post fields should include the request token, user name and password as follows:

CURLOPT_POSTFIELDS => "response_type=code&client_id=".$CLIENT_ID."&state=".$STATE."&request_token=".$REQ_TOKEN."&login=".$USER_LOGIN."&password=".$PASSWORD

At this point you should also set a cookie file:

  CURLOPT_COOKIEFILE => $COOKIE, (where $COOKIE is the path to the cookie file)

This will return another html text output, use the same method to grep the token which has the name "ic".

For the next step you're going to need to send a post request to the same url. It should include the postfields:

response_type=code&client_id=".$CLIENT_ID."&state=".$STATE."&redirect_uri=".$REDIRECT_URI."&doconsent=doconsent&scope=root_readwrite&ic=".$IC

Be sure to set the curl request to use the cookie file you set earlier like this:

CURLOPT_COOKIEFILE => $COOKIE,

and include the header in the request:

CURLOPT_HEADER => true,

At step (if done by browser) you will be redirected to a URL which looks as described above:

http://0.0.0.0(*redirect uri*)/?state=[box-generated_state_security_token]&code=[SOME_CODE] and note the "code=" value.

Grab the value of "code".

Final step!

send a new cur request to https//app.box.com/api/oauth2/token This should include fields:

CURLOPT_POSTFIELDS => "grant_type=authorization_code&code=".$CODE."&client_id=".$CLIENT_ID."&client_secret=".$CLIENT_SECRET,

This will return a string containing "access token", "Expiration" and "Refresh token". These are the tokens needed for the upload. read about the use of them here: https://box-content.readme.io/reference#upload-a-file

Hope this is somewhat helpful. P.S, I separated the https on purpuse (Stackoverflow wont let me post an answer with more than 1 url :D) this is for PHP cURL. It is also possible to do the same using Bash cURL.

like image 45
AmirW Avatar answered Sep 23 '22 06:09

AmirW