我试图让考拉与Omniauth合作.用户模型使用Omniauth登录Facebook,并且我想使用Koala作为客户端来拉取正在使用该应用的用户的朋友的列表.我似乎没有正确保存令牌:
调节器
@friends = Array.new if current_user.token graph = Koala::Facebook::GraphAPI.new(current_user.token) @profile_image = graph.get_picture("me") @fbprofile = graph.get_object("me") @friends = graph.get_connections("me","friends") end
DB架构
create_table "users",:force => true do |t| t.string "provider" t.string "uid" t.string "name" t.datetime "created_at" t.datetime "updated_at" t.string "token" end
用户模型有
def self.create_with_omniauth(auth) create! do |user| user.provider = auth["provider"] user.uid = auth["uid"] user.name = auth["user_info"]["name"] end end
Koala.rb初始化器有:
module Facebook CONFIG = YAML.load_file(Rails.root.join("config/facebook.yml"))[Rails.env] APP_ID = CONFIG['app_id'] SECRET = CONFIG['secret_key'] end Koala::Facebook::OAuth.class_eval do def initialize_with_default_settings(*args) case args.size when 0,1 raise "application id and/or secret are not specified in the config" unless Facebook::APP_ID && Facebook::SECRET initialize_without_default_settings(Facebook::APP_ID.to_s,Facebook::SECRET.to_s,args.first) when 2,3 initialize_without_default_settings(*args) end end alias_method_chain :initialize,:default_settings end
会话控制器有:
def create auth = request.env["omniauth.auth"] user = User.find_by_provider_and_uid(auth["provider"],auth["uid"]) || User.create_with_omniauth(auth) session[:user_id] = user.id session['fb_auth'] = request.env['omniauth.auth'] session['fb_access_token'] = omniauth['credentials']['token'] session['fb_error'] = nil redirect_to root_url end
解决方法
像您已经知道的问题是,fb_access_token仅在当前会话中可用,不可用于Koala.
您的用户型号是否有一列存储“令牌”?如果没有,请确保您在用户模型中有该列.当您在用户模型中有该列时,您将需要在创建用户时在其中存储某些内容(在User类中为create_with_omniauth方法).在Facebook的成功授权之后,您应该发现令牌字段填充了facebook oauth令牌.如果它被填充,那么你的考拉代码应该工作.在这种情况下,不需要在会话中存储facebook凭据.
然而,如果您没有从Facebook进行离线访问(这意味着访问仅在短时间内提供,则在会话中存储facebook凭据是有道理的,在这种情况下,您不应该使用“current_user.token”但是会话[“ fb_auth_token“]而不是考拉.
希望这可以帮助!
所以如果你想离线访问(长期保存的Facebook授权),请改变你的模型代码来存储fb_auth_token如下
# User model def self.create_with_omniauth(auth) create! do |user| user.provider = auth["provider"] user.uid = auth["uid"] user.name = auth["user_info"]["name"] user.token = auth['credentials']['token'] end end # SessionsController def create auth = request.env["omniauth.auth"] user = User.find_by_provider_and_uid(auth["provider"],auth["uid"]) || User.create_with_omniauth(auth) # Note i've also passed the omniauth object session[:user_id] = user.id session['fb_auth'] = auth session['fb_access_token'] = auth['credentials']['token'] session['fb_error'] = nil redirect_to root_url end
如果您有短期访问权限,请更改“其他”控制器以使用会话
# The other controller def whateverthissactionis @friends = Array.new if session["fb_access_token"].present? graph = Koala::Facebook::GraphAPI.new(session["fb_access_token"]) # Note that i'm using session here @profile_image = graph.get_picture("me") @fbprofile = graph.get_object("me") @friends = graph.get_connections("me","friends") end end