获取ng-token-auth以使用devise_token_auth

gam*_*mut 12 ruby-on-rails devise angularjs ionic

我有一个Rails和Ionic项目.后端使用devise_token_auth Gem和前端ng-token-auth; 这些应该是"无缝地"工作.

我已经将所有工作都注册并登录,这将返回一个有效的响应对象.但是,在我使用$ state.go('app.somepage')之后的任何进一步请求都会导致401 Unauthorized响应.

我觉得我实际上并没有将令牌存储在任何地方.有人可以帮忙吗?

以下是一些片段:

    .controller('LoginCtrl',['$scope', '$auth', '$state', function($scope, $auth, $state) {
    $scope.loginForm = {}
    $scope.handleLoginBtnClick = function() {
      console.log($scope.loginForm);
      $auth.submitLogin($scope.loginForm)
          .then(function(resp) {
            $state.go('app.feed');
          })
          .catch(function(resp) {
            console.log(resp.errors);
          });
    };
Run Code Online (Sandbox Code Playgroud)

州定义:

    .state('app', {
  url: "/app",
  abstract: true,
  templateUrl: "templates/menu.html",
  controller: 'AppCtrl',
  resolve: {
    auth: function($auth) {
      return $auth.validateUser();
    }
  }

})
Run Code Online (Sandbox Code Playgroud)

资源:

factory('Post', ['railsResourceFactory', 'apiUrl', function (railsResourceFactory, apiUrl) {
    return railsResourceFactory({
        url: apiUrl + '/posts',
        name: 'post'
    });
}]).
Run Code Online (Sandbox Code Playgroud)

在PostsCtrl中:

  $scope.loadFeed = function() {
    Post.query().then(function (posts) {
      $scope.posts = posts;
    }, function (error) {
      console.log( 'Did not get posts!'); ### THIS FIRES
    }).finally(function() {
      // Stop the ion-refresher from spinning
      $scope.$broadcast('scroll.refreshComplete');
    });
  };
Run Code Online (Sandbox Code Playgroud)

登录响应对象:

{"data":{"id":1,"provider":"email","uid":"1234","phone":null,"name":"Admin","image":null,"username":"admin"}}
Run Code Online (Sandbox Code Playgroud)

ApplicationController的顶部:

class ApplicationController < ActionController::Base
  include DeviseTokenAuth::Concerns::SetUserByToken

  before_filter :add_allow_credentials_headers
  before_filter :cors_preflight_check
  after_filter :cors_set_access_control_headers
  before_action :configure_permitted_parameters, if: :devise_controller?

  ..yadayada...

  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) << :phone
    devise_parameter_sanitizer.for(:sign_up) << :username
    devise_parameter_sanitizer.for(:sign_up) << :session

    devise_parameter_sanitizer.for(:sign_in) << :phone
    devise_parameter_sanitizer.for(:sign_in) << :username
    devise_parameter_sanitizer.for(:sign_in) << :session
  end
Run Code Online (Sandbox Code Playgroud)

还有一些用户在轨道侧的默认型号.

Rails日志:

Started GET "/posts" for 192.168.83.26 at 2015-02-24 23:29:02 -0500
Processing by PostsController#index as JSON
  Parameters: {"post"=>{}}
Filter chain halted as :authenticate_user! rendered or redirected
Completed 401 Unauthorized in 1ms (Views: 0.2ms | ActiveRecord: 0.0ms)
Run Code Online (Sandbox Code Playgroud)

如果有人能提供一些很棒的见解.我很乐意根据需要发布更多片段.

gam*_*mut 8

事实证明,解决方案相当简单.似乎在每个人提供的大多数示例中,他们忽略了允许access-token以及所有其他CORS标头.

我们在这个底部使用了机架式config.ru:

require 'rack/cors'
use Rack::Cors do

  # allow all origins in development
  allow do
    origins '*'
    resource '*',
             :headers => :any,
             :expose  => ['access-token', 'expiry', 'token-type', 'uid', 'client'],
             :methods => [:get, :post, :delete, :put, :options]
  end
end
Run Code Online (Sandbox Code Playgroud)

然后在ApplicationController.rb中:

  before_filter :add_allow_credentials_headers
  skip_before_filter :verify_authenticity_token
  before_filter :cors_preflight_check
  after_filter :cors_set_access_control_headers


  def cors_set_access_control_headers
    headers['Access-Control-Allow-Origin'] = '*'
    headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, OPTIONS'
    headers['Access-Control-Allow-Headers'] = 'Origin, Content-Type, Accept, Authorization, Token'
    headers['Access-Control-Max-Age'] = '1728000'
  end

  def cors_preflight_check
    if request.method == 'OPTIONS'
      headers['Access-Control-Allow-Origin'] = '*'
      headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, OPTIONS'
      headers['Access-Control-Allow-Headers'] = 'X-Requested-With, X-Prototype-Version, Token'
      headers['Access-Control-Max-Age'] = '1728000'

      render :text => '', :content_type => 'text/plain'
    end
  end

  def add_allow_credentials_headers
    # https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#section_5
    #
    # Because we want our front-end to send cookies to allow the API to be authenticated
    # (using 'withCredentials' in the XMLHttpRequest), we need to add some headers so
    # the browser will not reject the response
    response.headers['Access-Control-Allow-Origin'] = request.headers['Origin'] || '*'
    response.headers['Access-Control-Allow-Credentials'] = 'true'
  end
Run Code Online (Sandbox Code Playgroud)

  • 不知道为什么没有投票或基本文档中没有涉及.这对我来说是必须的,我不认为我们做任何不寻常的事情. (2认同)