2017-04-06 60 views
0

尝试使用ajax登录用户,因此而不是使用sign_in_and_redirect我使用了sign_in方法。用户在使用ajax,devise和omniauth时登录失败

函数结束时的signed_in_user?如预期的那样是真实的,但是当再次点击服务器时signed_in_user?其实是错误的。 我错过了什么?

class OmniauthCallbacksController < Devise::OmniauthCallbacksController 
     respond_to :json 
     def all_omniauth_providers 
     @user = User.find_for_oauth(request.env["omniauth.auth"]) 
     if @user.persisted? 
      # sign_in_and_redirect @user, :event => :authentication 
      if (sign_in(@user, :event => :authentication)) 
       respond_with resource, location: after_sign_in_path_for(resource) 
      else 
       # respond_with resource, location: root_path 
      end 
     else 
      session["devise.#{provider}_data"] = request.env["omniauth.auth"] 
      render :status => 401, :json => { :errors => alert } 
     end 
     end 

     alias_method :facebook, :all_omniauth_providers 
    end 

和JavaScript连接:

<script type="text/javascript"> 
     window.fbAsyncInit = function() { 
      // init the FB JS SDK 
      FB.init({ 
       appId  : '<%=Rails.application.secrets.facebook_app_id%>', // App ID from the App Dashboard 
       channelUrl : '//localhost:3000/channel.html', // Channel File for x-domain communication 
       status  : true, // check the login status upon init? 
       cookie  : true, // set sessions cookies to allow your server to access the session? 
       xfbml  : true, // parse XFBML tags on this page? 
       version : 'v2.5' 
      }); 

      // Additional initialization code such as adding Event Listeners goes here 

     }; 

    (function(d, s, id){ 
     var js, fjs = d.getElementsByTagName(s)[0]; 
     if (d.getElementById(id)) {return;} 
     js = d.createElement(s); js.id = id; 
     js.src = "//connect.facebook.net/en_US/sdk.js"; 
     fjs.parentNode.insertBefore(js, fjs); 
    }(document, 'script', 'facebook-jssdk')); 

     $(function() { 
      $('#facebook-connect').click(function(e) { 
       e.preventDefault(); 

       FB.login(function(response) { 
       if(response.authResponse) { 
        $.ajax({ 
        type: 'POST', 
        url: '/users/auth/facebook/callback', 
        dataType: 'json', 
        data: {signed_request: response.authResponse.signedRequest}, 
        success: function(data, textStatus, jqXHR) { 
         $('#close').click(); 
         $("#share").jsSocials("option", "url", "<%=url%>?ref=" + data.id); 
         $('#loginout_button').html("<%= j button_to t('auth.logout'), destroy_user_session_path, :class=>'btn btn-default navbar-btn navbar-left btn-xs btn-success', :method => :delete %>"); 
        }, 
        error: function(jqXHR, textStatus, errorThrown) { 
         $('.server_error').addClass('alert alert-danger').html("<%= t('auth.login_failed') %>"); 
         shakeModal(); 
        } 
        }); 
       } 
       } 
       , {scope: 'email'}); 

      }); 
     }); 


     $(function() { 
      $('#facebook-logout').click(function(e) { 
       e.preventDefault(); 

       FB.getLoginStatus(function(response) { 
       if(response.authResponse) { 
        FB.logout(); 
       } 
       } 
       , {scope: 'email'}); 

      }); 
     }); 
    </script> 
    <!-- end Facebook connect script --> 
+0

您可能需要包含进行登录的JS。我怀疑一个头/ cookie /?没有在客户端上设置。用JavaScript登录函数更新了 –

+0

。奇怪的是,一旦我刷新页面,服务器返回user_signed_in?与预期的一样真实...... – user664859

回答

0

我花了一段时间,但问题是在CSRF认证是为我所用Ajax和失败色器件后登录它改变了CSRF令牌,你有在你的头:

<%= csrf_meta_tag %> 
在应用控制器

我有这样的: protect_from_forgery有:null_session

,我不得不跳过验证(轨道5):

protect_from_forgery with: :exception, unless: -> { request.format.json? } 

我尝试也在使用一些技巧,从这里更改登录后的CSRF标题: WARNING: Can't verify CSRF token authenticity rails

,但未能。所以这就是现在的工作方式。