Facebook JS SDK cookie和omniauth-facebook

时间:2016-04-29 15:14:28

标签: ruby-on-rails facebook cors omniauth-facebook

我在我的项目中使用Facebook实施登录,该项目包含两个应用程序:

  • 前端:纯HTML + CSS + JS;
  • 后端:Rails 5 API(omniauth 1.3.1,omniauth-facebook 3.0.0);

即使在我的本地环境中,这两个应用程序都在不同的域上运行(frontend.dev.azk.ioapi.dev.azk.io)。

我在我的前端应用程序中运行FB SDK,一旦登录成功,我应该ping OAuth回调(http://api.dev.azk.io/api/v1/users/auth/facebook/callback),以便omniauth-facebook可以访问fbsr_XXX cookie,解析它并将当前的accessToken换成长期的。{/ p>

主要问题是FB SDK设置的cookie属于前端域,并且未在API的请求标头中发送,即omniauth-facebook无法访问它:

ERROR -- omniauth: (facebook) Authentication failure! no_authorization_code: OmniAuth::Strategies::Facebook::NoAuthorizationCodeError, must pass either a `code` (via URL or by an `fbsr_XXX` signed request cookie)

此时,我想到了两种可能的方法:

1)检查CORS和AJAX配置,以便cookie可以在请求中发送给API;

2)Parse前端的FB响应(使用this algorithm)并将code attribute发送给API;

方法1

受SO incredibly similar question的启发,我做了以下配置:

的routes.rb

devise_for :users, path_prefix: 'api/v1', controllers: {
  sessions:           'api/v1/sessions',
  registrations:      'api/v1/registrations',
  omniauth_callbacks: 'api/v1/omniauth_callbacks',
}

application.rb中

config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'frontend.dev.azk.io'
    resource '*',
      headers: :any,
      credentials: true,
      methods: [:get, :put, :post, :patch, :delete, :options]
  end
end

devise.rb

config.omniauth :facebook, oauth_providers['facebook']['app_id'], oauth_providers['facebook']['secret'], {
  scope: 'email,user_birthday,user_about_me,public_profile',
  provider_ignores_state: true
}

客户端应用

$.ajax({
  type: 'GET',
  url: 'http://api.dev.azk.io/api/v1/users/auth/facebook/callback',
  crossDomain: true,
  xhrFields: { withCredentials: true },
}) . . .

然而,这还不足以发送fbsr_XXX cookie(存在于浏览器中)。我有什么遗失的吗?

方法2

由于omniauth-facebook无法访问上述Cookie,因此我决定解析FB返回的signedRequest值并发送code attribute以获取API。< / p>

但是,似乎omniauth-facebook生成的callback_url与前一个请求中使用的ERROR -- omniauth: (facebook) Authentication failure! invalid_credentials: OAuth2::Error, : {"error":{"message":"Error validating verification code. Please make sure your redirect_uri is identical to the one you used in the OAuth dialog request","type":"OAuthException","code":100,"fbtrace_id":"BavpcDFblHy"}} 不匹配:

proc sql;
   create table ca_m_service as
   select a.month_key, a.service_key, a.tot_revenue, a.TOT_REVENUE_DISCNT, a.euser_key, b.*
   from fr_dme.M_service_rev_by_euser_f  as a
   inner join code_remise_ass as b
     on a.service_key = b.service_key
   inner join code_remise_ass as c 
     on a.service_key = c.parent_service_key
   where a.month_key between 201504 and 201509;
quit;

我真的不喜欢第二种方法,我认为第一种方式更优雅。我认为这个过程应该很简单,可能我错过了一些愚蠢的东西。

0 个答案:

没有答案