我已经学习了本教程,并且它的工作是正确的。
[在以下答案后更新]我已经将代码移动到应用程序控制器(以前定义为助手),以确定当前用户是否登录
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
helper_method :current_user
def current_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
end
end
我已经创建了一个模块来创建客户端对象并进行api调用,这个功能可能被一个或多个对象使用,所以将其创建为模块而不是控制器似乎是个好主意。
require 'base64'
require 'rubygems'
require 'json'
require 'google/api_client'
require 'google/api_client/client_secrets'
require 'net/https'
require 'uri'
module GoogleClient
include ApplicationController
PLUS_LOGIN_SCOPE = 'https://www.googleapis.com/auth/plus.login'
# Build the global client
$credentials = Google::APIClient::ClientSecrets.load("#{Rails.root}/config/client_secret_xxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com.json")
$authorization = Signet::OAuth2::Client.new(
:authorization_uri => $credentials.authorization_uri,
:token_credential_uri => $credentials.token_credential_uri,
:client_id => $credentials.client_id,
:client_secret => $credentials.client_secret,
:redirect_uri => $credentials.redirect_uris.first,
:scope => PLUS_LOGIN_SCOPE)
$client = Google::APIClient.new(options = {:application_name => 'xxx-xxx-xxx'} )
def GoogleClient.get_people
if current_user
# Authorize the client and construct a Google+ service.
$client.authorization.update_token!(current_user.oauth_token.to_hash)
plus = $client.discovered_api('plus', 'v1')
# Get the list of people as JSON and return it.
response = $client.execute!(plus.people.list,
:collection => 'visible',
:userId => 'me').body
content_type :json
puts response
else
redirect_to root_url
end
end
end
用户模型为;
require 'google_client'
class User < ActiveRecord::Base
include GoogleClient
# after_save GoogleClient.connect
def self.from_omniauth(auth)
where(provider: auth["provider"], uid: auth["uid"]).first_or_initialize.tap do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name
user.email = auth.info.email
user.oauth_token = auth.credentials.token
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
user.save!
end
在控制台中测试会导致
2.1.0:001>GoogleClient.get_peopleNoMethodError:ApplicationHelper的未定义方法"helper_method":模块
是否可以调用模块中的helper方法?如果模块不正确,我应该如何实现此代码
**更新正确的模块代码,但api请求有一个重定向uri错误**在本文中解释
"请注意,/lib中的模块不是自动加载的。相反,您需要在config/application.rb文件配置块中添加此行:">
config.autoload_paths += %W(#{config.root}/lib)
用户模型
class User < ActiveRecord::Base
include Google::GoogleClient
def self.from_omniauth(auth)
where(provider: auth["provider"], uid: auth["uid"]).first_or_initialize.tap do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name
user.email = auth.info.email
user.oauth_token = auth.credentials.token
user.oauth_expires_at = Time.at(auth.credentials.expires_at)
user.save!
end
end
if current_user
self.get_people()
else
redirect_to root_url
end
end
'lib/google/google_client.rb'
require 'google/api_client'
require 'google/api_client/client_secrets'
require 'google/api_client/auth/installed_app'
module Google
module GoogleClient
# Initialize the client.
client = Google::APIClient.new(
:application_name => 'xxx-xxx',
:application_version => '1.0.0'
)
# Initialize Google+ API. Note this will make a request to the
# discovery service every time, so be sure to use serialization
# in your production code. Check the samples for more details.
# Load client secrets from your client_secrets.json.
client_secrets = Google::APIClient::ClientSecrets.load("#{Rails.root}/config/client_secret_XXXXXXXXXXXXXXXXXXXXXXXx.apps.googleusercontent.com.json")
# Run installed application flow. Check the samples for a more
# complete example that saves the credentials between runs.
flow = Google::APIClient::InstalledAppFlow.new(
:client_id => client_secrets.client_id,
:client_secret => client_secrets.client_secret,
:scope => ['https://www.googleapis.com/auth/plus.me']
)
client.authorization = flow.authorize
def get_people
# Make an API call.
result = client.execute(
:api_method => plus.activities.list,
:parameters => {'collection' => 'public', 'userId' => 'me'}
)
puts result.data
end
end
end
将两者都移动到ApplicationController:
def current_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user
这将为您提供一个在控制器、辅助对象和视图中工作的current_user
方法。