设计令牌身份验证+保存Facebook信息

时间:2015-08-05 12:54:27

标签: ruby-on-rails ruby angularjs devise

我正在使用Devise auth token gem和ng-token auth来验证我的单页应用。除了使用电子邮件注册外,还可以选择通过Facebook注册。有用。

我的问题是,对于我的Fb请求范围,我设置为获取user_friends,email和public_info,但是当我收到请求时,我没有看到auth_hash request.env ['omniauth.auth']。这在omniauth-facebook gem documentation中有所描述。

基本上我想保存FB给出的关于我的数据库中用户的内容。你会怎么做?

2 个答案:

答案 0 :(得分:1)

我使用Ionic2应用程序的这个终点,对于Rails 5 API上的Facebook登录请求,使用KoalaDevise Token Auth,因此您应该能够在任何Rails 5应用程序上进行复制:

def facebook
  @graph = Koala::Facebook::API.new(oauth_params[:token], ENV["FACEBOOK_SECRET"])
  @profile = @graph.get_object("me?fields=email,first_name,last_name,picture.type(large)")

  unless @user = User.where(email: @profile["email"])&.first
    @user = User.new(email: @profile["email"])
  end
  #
  # Here you will make your logic for saving Facebook's data on your User model,
  # customize accordingly
  #
  if @user.new_record?
    p = SecureRandom.urlsafe_base64(nil, false)
    @user.password = p
    @user.password_confirmation = p
    #
    # "Passwordless" login, user must set password after registering,
    # or be forever haunted by indecipherable SecureRandom value
    #
    @user.name = @profile["first_name"]+ " " + @profile["last_name"]
    @user.remote_avatar_url = @profile["picture"]["data"]["url"]
    @user.confirmed_at = Time.now
    @user.uid = @profile["id"]
    @user.provider = 'Facebook'
  end

  @client_id = SecureRandom.urlsafe_base64(nil, false)
  @token     = SecureRandom.urlsafe_base64(nil, false)
  @user.tokens[@client_id] = {
    token: BCrypt::Password.create(@token),
    expiry: (Time.now + DeviseTokenAuth.token_lifespan).to_i
  } 
  auth_header = @user.build_auth_header(@token, @client_id)
  # update the response header
  response.headers.merge!(auth_header)
  @user.save!
  if sign_in(:user, @user, store: false, bypass: false)
    render json:  {
      data: @user.token_validation_response 
    }
  end
end

将POST路由指向此路径,并将authResponse.accessToken从Facebook请求传递为params[:token]。 Voilà,认证魔术!

答案 1 :(得分:0)

我没有使用Angular和Rails如何做到这一点,但这就是我在Rails应用程序中的做法。

def show 
 #controller action
 @FbInfoforFrontEnd = FbModel.from_omniauth(request.env["omniauth.auth"])
end

在FbModel模型中,我实现了保存令牌和其他信息的机制

def self.from_omniauth(auth)
 #FbModel model method
 oauth = Koala::Facebook::OAuth.new(AppId, AppSecret)
 new_access_info = oauth.exchange_access_token_info auth.credentials.token
 new_access_token = new_access_info["access_token"]
 new_access_expires_at = DateTime.now + new_access_info["expires"].to_i.seconds
 return FbModel.where(provider: auth.provider,
                      uid: auth.uid)
               .first_or_create(provider: auth.provider,
                         uid: auth.uid,
                         name: auth.info.name)
               .update_attributes(oauth_expires_at: new_access_expires_at,
                                  oauth_token: new_access_token)
end

我希望这能回答你的问题