BOX API Integration With RubyOnRails (OAuth 2.0)

alok rawat
ITNEXT
Published in
3 min readDec 8, 2017

--

Login By Using OAuth 2.0

Box | Secure Content & Online File Sharing for Businesses

Click here to share this article on LinkedIn »

Box offers secure content management and collaboration for individuals, teams, and businesses, enabling secure file sharing and access to your files online.

For OAuth2.0, please refer to the following link:
http://www.bubblecode.net/en/2016/01/22/understanding-oauth2/

To configure the application in BOX, follow these steps:

Step1: Create a developer account

https://app.box.com/signup/o/default_developer_offer

If you have then ignored.

Step2: Follow the steps in the below link:

https://box-content.readme.io/docs/oauth-20

Step3: After completing the app setting in BOX, create a rails application. Let us suppose, controller name is box_api_controller.rb

In box_api_controller.rb file,

Create a make request on login button

def make_request
#Check access token expire or not.
check_access_token_expire = check_access_token_expire_dt
if check_access_token_expire.split("-")[0] == "access_token"
#Create client by passing Token
@box_client = Boxr::Client.new(check_access_token_expire.split("-")[1])
cookies[:token] = check_access_token_expire.split("-")[1]
else
if check_access_token_expire.split("-")[0] == "refresh_token"
#Call method
create_post_req_url("refresh_token","refresh_token",check_access_token_expire.split("-")[1])
else
# kick off authorization flow
parameters = "response_type=code&client_id=<your client id>&redirect_uri=<your application url>/handle_user_decision/&state=security_token"
url = "https://account.box.com/api/oauth2/authorize?#{parameters}"
redirect_to url
end
end end

##After authorized the client id, get code in response
def handle_user_decision
# kick off authorization flow
#Get authorization code
code_url = Rack::Utils.parse_query URI(request.original_url).query
code = code_url["code"]
#Call method
create_post_req_url("authorization_code","code", code)
end

Create a post URL

def create_post_req_url(grant_type,header, code)
#Set oauth2 url
uri = URI.parse("https://api.box.com//oauth2//token")
#Passing parameter
data = "grant_type=#{grant_type}&#{header}=#{code}&client_id=<your client id>&client_secret=<your client secret key>"
#Set header
headers = {"Content-Type" => "application/x-www-form-urlencoded"}
#Get http request
http = Net::HTTP.new(uri.host,uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
#Do post the URL
response = http.post(uri.path,data.to_s,headers)
#Check response
if response.code != "200"
flash[:alert] ="エラーが発生しました。管理者に連絡してください。エラーの内容:#{response.code} #{JSON.parse(response.body)}"
else
#flash[:alert] ="#{response.body.to_json}"
parsed = JSON.parse(response.body) # returns a hash
token = parsed["access_token"]
cookies[:token] = nil
cookies[:token] = token
if grant_type == "authorization_code"
#Insert BOX access token details
user = "<your drive user name>"
insert_access_token(user, token, parsed["refresh_token"], Time.now)
else
if grant_type == "refresh_token"
#Update BOX access token
updt_access_token(user, token, code, parsed["refresh_token"], Time.now)
end
end
redirect_to box_api_index_path
end
end

Other helper methods:-

Check access_token expire or not.

def check_access_token_expire_dt
@access_token_time = BoxApiAccessToken.getaccesstokentime
if !@access_token_time.blank?
@access_token_time.each do |token_details |
if token_details.access_token_dt != nil
if token_details.new_access_token_dt.to_datetime.new_offset(Rational(9, 24)).strftime('%Y/%m/%d %H:%M') < Time.now.to_datetime.new_offset(Rational(9, 24)).strftime('%Y/%m/%d %H:%M')
check_access_token_expire_dt = "refresh_token-#{token_details.refresh_access_token}"
return check_access_token_expire_dt
else
check_access_token_expire_dt = "access_token-#{token_details.access_token}"
return check_access_token_expire_dt
end
else
check_access_token_expire_dt = "new_token-req_new_token"
return check_access_token_expire_dt
end
end
else
check_access_token_expire_dt = "new_token-req_new_token"
return check_access_token_expire_dt
end
end

Insert access_token details in DB

def insert_access_token(user,access_token,refresh_access_token,access_token_dt)
@box_access_token = BoxApiAccessToken.new(
:user => user,
:access_token => access_token,
:refresh_access_token => refresh_access_token,
:access_token_dt => access_token_dt)

#Save User Device Data
@box_access_token.save
end

#Update access_token,refresh_access_token,access_token_dt details in DB
def updt_access_token(user,access_token, refresh_access_token,new_refresh_access_token,access_token_dt)
#@box_access_token_updt = BoxApiAccessToken.find_refresh_access_token(refresh_access_token)
@box_access_token_updt = BoxApiAccessToken.find_by_refresh_access_token(refresh_access_token)
attributes = {:access_token => access_token,:access_token_dt => access_token_dt, :refresh_access_token => new_refresh_access_token, :updated_at => access_token_dt}
#Update the object
@box_access_token_updt.update_attributes(attributes)
end

In model,

class BoxApiAccessToken < ActiveRecord::Base
scope :getaccesstokentime, lambda {
select("id,access_token,refresh_access_token,substring(cast(access_token_dt as varchar),0,17) as access_token_dt,substring(cast(access_token_dt + interval '60 minute' as varchar),0,17) as new_access_token_dt ").order(:id => "desc").limit(1)
}
end

In index.html.erb file

<%= form_tag(:controller => "box_api", :action => 'make_request') do |f| %>
<div class="form-group"><%= submit_tag("Box Login", class: "btn btn-primary") %></div><% end %>

Here is my migration file

class CreateBoxApiAccessTokens < ActiveRecord::Migration
def change
create_table :box_api_access_tokens do |t|
t.string :user, :limit => 100, :null => false
t.string :access_token, :limit => 500
t.string :refresh_access_token, :limit => 500
t.datetime :access_token_dt, :limit => 50
t.datetime :created_at, :null => false
t.string :created_by, :limit => 50
t.datetime :updated_at
t.string :updated_by, :limit => 50
t.boolean :del_flag, :default => false
end
execute 'alter table box_api_access_tokens alter column created_at set default now()'
end
end

Please note that, Using the Access and Refresh Tokens The access_token is the actual string needed to make API requests. Each access_token is valid for 1 hour. In order to get a new, valid token, you can use the accompanying refresh_token. Each refresh_token is valid for one use in 60 days. Every time you get a new access_token by using a refresh_token, we reset your timer for the 60 day period and hand you a new refresh_token.

This means that as long as your users use your application once every 60 days, their login is valid forever.

For more details, please refer BOX API document.

Enjoy Coding.

Thanks & Best Regards,
Alok Rawat

Originally published at qiita.com.

--

--

Chief Engineer | Project Manager at NTT DATA INTELLILINK Corporation,Tech Enthusiast, Learner https://alokrawat050.github.io/alokrawat.github.io/