Working on a simple Google Analytics API dashboard app where signed_up users can see their data and receive emails along with other stuff.
As of now only a crude setup is implemented where
1. Devise is implemented
2. current_user
authorizes app with Google
Need to ensure if the code is setup properly, here it is
In /lib/google_api.rb
require 'google/apis/analytics_v3'
class GoogleAPI
GOOGLE_API_CLIENT_ID = 'xxx'
GOOGLE_API_CLIENT_SECRET = 'xxx'
GOOGLE_OAUTH2_URL = 'http://ift.tt/IlrJzQ'
GOOGLE_ACCESS_TOKEN_URL = 'http://ift.tt/1yJFQ0y'
GOOGLE_CALLBACK_URL = 'http://localhost:3000/google_callback'
attr_accessor :ga_id, :client, :user
def initialize(user, ga_id=nil)
@user = user
@ga_id = ga_id if ga_id
@client = Signet::OAuth2::Client.new(
client_id: GOOGLE_API_CLIENT_ID,
client_secret: GOOGLE_API_CLIENT_SECRET,
authorization_uri: GOOGLE_OAUTH2_URL,
scope: Google::Apis::AnalyticsV3::AUTH_ANALYTICS_READONLY,
token_credential_uri: GOOGLE_ACCESS_TOKEN_URL,
redirect_uri: GOOGLE_CALLBACK_URL,
additional_parameters: { access_type: :offline, approval_prompt: :force }
)
end
def authorization_uri
@client.authorization_uri.to_s
end
def init_refresh_token(authorization_code)
@client.update!(code: authorization_code)
# @client.fetch_access_token!['access_token'] gives you the access token
@client.fetch_access_token!['refresh_token']
end
def reauthorize!(refresh_token)
@client.update!(refresh_token: refresh_token, grant_type: :refresh_token)
access_token = @client.fetch_access_token!['access_token']
@client.update!(access_token: access_token)
end
def init_service(refresh_token)
self.reauthorize!(refresh_token)
service = Google::Apis::AnalyticsV3::AnalyticsService.new
service.authorization = @client
service
end
end
In Views
<h1>Logged in as <%= current_user.email %></h1>
Click <%= link_to 'here', @google_oauth_service.authorization_uri %> to authorize app.
<br>
Go to your - <%= link_to "Google Dashboard", analytics_path %>
In Application Controller
require "#{Rails.root}/lib/google_api"
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
def google_oauth_service
if current_user.ggl_re_token
render :notice => "Already Authorized"
else
@google_oauth_service = GoogleAPI.new(current_user, current_user.ga_id)
end
end
end
The condition in application controller does not work, it still redirects to Google even if the User has already authorized.
In GoogleController.rb
require "#{Rails.root}/lib/google_api"
class GoogleController < ApplicationController
before_action :authenticate_user!
before_action :google_oauth_service
def google_callback
if params[:code]
google_oauth_service = GoogleAPI.new(current_user)
refresh_token = google_oauth_service.init_refresh_token(params[:code])
#store the refresh token in database for later access from server
current_user.ggl_re_token = refresh_token
current_user.save
redirect_to url_for(:action => :analytics)
end
end
def analytics
google_oauth_service = GoogleAPI.new(current_user)
# TODO next two commands in scheduled task
@service = google_oauth_service.init_service(current_user.ggl_re_token) #refresh_token from your database
@account_summaries = @service.list_account_summaries
end
end
ISSUES FACING
1. Is the refresh_tokenreauthorize!
method be perfect for production? See top google_api.rb
2. For current_user when the link is clicked, how to make sure if Analytics is already authorized for the current_user, it does not redirect to the Google page but to a simple notification?
I tried it by checking if a refresh_token is there in the User model but it still redirects.
Sorry if its too much too ask but this scenario is not uncommon.
If you were executing this with a user model, what are the steps/conditions you would ensure is setup for a foolproof implementation.
Aucun commentaire:
Enregistrer un commentaire