Omniauth:“缺少模板错误” - Ruby on Rails

时间:2015-02-18 21:40:03

标签: ruby-on-rails ruby angularjs omniauth omniauth-linkedin

我正在构建一个通过LinkedIn进行身份验证的API,然后将我们的令牌返回给客户端。

客户端将以AngularJS编写,并将单独运行。

验证网址:http://example.com/users/auth/linkedin

验证后出现以下错误:

Missing template users/omniauth_callbacks/linkedin, 
devise/omniauth_callbacks/linkedin, devise/linkedin,
application/linkedin with {
    :locale=>[:en],
    :formats=>[:html],
    :variants=>[],
    :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]
}.

Searched in: * "/usr/local/lib/ruby/gems/2.2.0/gems/web-console-2.0.0/lib/action_dispatch/templates" * "/usr/local/Cellar/ruby/2.2.0/lib/ruby/gems/2.2.0/gems/devise-3.4.1/app/views"

我使用以下特殊宝石:

# Authentication
gem 'devise'
gem 'devise-token_authenticatable'
gem 'omniauth'
gem 'omniauth-oauth'
gem 'omniauth-linkedin'

# API Wrappers
gem 'linkedin'

源代码

配置/ routes.rb中

# filename: routes.rb
# encoding: utf-8

Rails.application.routes.draw do

  #
  # API v1 Endpoints
  #

  scope '/api' do
    ## Authentication
    devise_for :users,
      :skip => [:sessions, :password, :registrations, :confirmation],
      :controllers => {
        :omniauth_callbacks => "users/omniauth_callbacks",
        :registrations      => "users/registrations",
        :sessions           => "users/sessions"
      }

    ## User specific routes
    scope '/users' do
      devise_scope :user do
        post '/check'   => 'users/users#is_user', as: 'is_user'
        post '/current' => 'users/sessions#get_current_user', as: 'current_user'
      end
    end
  end
end

应用程序/控制器/ application_controller.rb

# filename: application_controller.rb
# encoding: utf-8

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception

  before_filter :set_cors_headers
  before_filter :cors_preflight

  def set_cors_headers
    headers['Access-Control-Allow-Origin']  = AppConfig.client['origin']
    headers['Access-Control-Allow-Methods'] = 'GET,POST,PUT,DELETE,OPTIONS'
    headers['Access-Control-Allow-Headers'] = '*'
    headers['Access-Control-Max-Age']       = "3628800"
  end

  def cors_preflight
    head(:ok) if request.method == :options
  end
end

应用程序/控制器/用户/ omniauth_callbacks_controller.rb

# filename: omniauth_callbacks_controller.rb
# encoding: utf-8

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  ## Sign in / up with LinkedIn
  def linkedin
    auth_hash = request.env["omniauth.auth"]

    auth = Authorization.find_by_provider_and_uid("linkedin", auth_hash['uid'])

    if auth
      ## User already exists
      user = auth.user
    else
      ## User already signed in
      unless current_user
        unless user = User.find_by_email(auth_hash['info']['email'])
          user = User.create({
            first_name: auth_hash['info']['first_name'],
            last_name:  auth_hash['info']['last_name'],
            email:      auth_hash['info']['email'],
            password:   Devise.friendly_token[0,8]
          })
        end
      ## Sign user in
      else
        user = current_user
      end

      # Create an authorization for the current user
      unless auth = user.authorizations.find_by_provider(auth_hash["provider"])
        auth = user.authorizations.build(provider: auth_hash["provider"])
        user.authorizations << auth
      end

      auth.update_attributes({
          uid:    auth_hash['uid'],
          token:  auth_hash['credentials']['token'],
          secret: auth_hash['credentials']['secret'],
        })

      # Return user
      user
    end
  end
end

应用程序/控制器/用户/ registrations_controller.rb

# filename: registrations_controller.rb
# encoding: utf-8

class Users::RegistrationsController < Devise::RegistrationsControllerú
  skip_before_filter :verify_authenticity_token

  respond_to :json

  def create
    # Create the user
    build_resource(sign_up_params)

    # Try to save them
    if resource.save
      sign_in resource
      render status: 200,
        json: {
          success: true,
          info: "Registered",
          data: {
            user: resource,
            auth_token: current_user.authentication_token
          }
        }
    else
      # Otherwise fail
      render status: :unprocessable_entity,
        json: {
          success: false,
          info: resource.errors,
          data: {}
        }
  end

end

应用程序/控制器/用户/ sessions_controller.rb

# filename: omniauth_callbacks_controller.rb
# encoding: utf-8

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  ## Sign in / up with LinkedIn
  def linkedin
    auth_hash = request.env["omniauth.auth"]

    auth = Authorization.find_by_provider_and_uid("linkedin", auth_hash['uid'])

    if auth
      ## User already exists
      user = auth.user
    else
      ## User already signed in
      unless current_user
        unless user = User.find_by_email(auth_hash['info']['email'])
          user = User.create({
            first_name: auth_hash['info']['first_name'],
            last_name:  auth_hash['info']['last_name'],
            email:      auth_hash['info']['email'],
            password:   Devise.friendly_token[0,8]
          })
        end
      ## Sign user in
      else
        user = current_user
      end

      # Create an authorization for the current user
      unless auth = user.authorizations.find_by_provider(auth_hash["provider"])
        auth = user.authorizations.build(provider: auth_hash["provider"])
        user.authorizations << auth
      end

      auth.update_attributes({
          uid:    auth_hash['uid'],
          token:  auth_hash['credentials']['token'],
          secret: auth_hash['credentials']['secret'],
        })

      # Return user
      user
    end
  end
end

应用程序/控制器/用户/ users_controller.rb

# filename: users_controller.rb
# encoding: utf-8

class Users::UsersController < Devise::SessionsController
  protect_from_forgery with: :exception, except: [:is_user]

  respond_to :json

  ## Check if user exists by email
  def is_user
    #authenticate_user!
    render status: 200, json: {
        success: !User.find_by_email(params[:email]).blank?
      }
  end

end

1 个答案:

答案 0 :(得分:1)

linkedin类中的Users::OmniauthCallbacksController方法未明确renderredirect,因此它尝试隐式呈现linkedin模板(通常是linkedin.html.erb

根据您的代码,您可能希望在代码中使用render user.to_json或类似内容,以便有角度的api可以获得可以使用的内容。