0

我主要来自 PHP 和 ASP.NET 背景。最近我涉足 Ruby 并开始与Padrino. 不太像 Rails,也不太像 Sinatra。

我正在使用第一个严肃的应用程序Padrino,很快就卡住了,感谢您的帮助。

我认为的问题在于Padrino Admin. 我正在尝试让用户使用 Omniauth 登录我Facebook网站

我一直在关注本教程:Padrino 和 Omniauth 概述

该应用程序托管在Heroku.

结果Facebook登录时,创建了一个帐户(在数据库中)。但是当我到达限制区域时,我会被重定向回登录页面。

这就是我所拥有的。

应用程序.rb

module PDeen
  class App < Padrino::Application

    register Padrino::Admin::AccessControl

    register SassInitializer
    register Padrino::Rendering
    register Padrino::Mailer
    register Padrino::Helpers

    enable :sessions

    # get '/' do 
    #   "Welcome to me @ internet"
    # end

    use OmniAuth::Builder do
      provider :facebook,  'xxxx', 'yyyy' 
      # provider :facebook, 'app_id', 'app_secret'
    end

    set :login_page, "/login" # determines the url login occurs

    access_control.roles_for :any do |role|
      role.protect "/profile"
      role.protect "/admin" # here a demo path
    end

    # now we add a role for users
    access_control.roles_for :users do |role|
      role.allow "/profile"
    end

    get :index do 
      'Hi'
    end

    get :login do
      slim :'index'
    end

    get :profile do
      content_type :text
      current_account.to_yaml
    end

    get :destroy do
      set_current_account(nil)
      redirect url(:index)
    end

    get :auth, :map => '/auth/:provider/callback' do
      auth    = request.env["omniauth.auth"]
      # account = Account.find_by_provider_and_uid(auth["provider"], auth["uid"]) || 
      #           Account.create_with_omniauth(auth)
      # 
      account = User.first( :provider => auth["provider"], :uid => auth["uid"] )

      if ! account.nil?
        set_current_account(account)  
        redirect :existing
      end

      if account.nil? 
        # Create account
        account           = User.new 
        account.uid       = auth['uid']
        account.name      = auth['name']
        account.provider  = auth['provider']
        account.email     = auth['user_info']['email'] if auth['user_info']
        account.role      = 'users'

        account.save
      end 

      set_current_account(account)
      #redirect "http://" + request.env["HTTP_HOST"] + url(:profile)
      redirect :new
    end

    get :existing do 
      'existing'
    end

    get '/session/test' do 
      session[:test] = 'This is a test'
    end

    get '/session/print' do 
      "You saved: #{session[:test]}"
    end
  end
end

用户.rb

class User
  include DataMapper::Resource

  # property <name>, <type>
  property :id, Serial
  property :name, String
  property :email, String
  property :role, String
  property :uid, String
  property :provider, String

end

会发生什么>>

  1. 项目清单
  2. 我去[server]/profile〜>重定向到[server]/login
  3. 我点击 Facebook ~> 进入页面以接受应用程序 ~> 重定向回应用程序
  4. 我去[server]/profile〜>重定向到[server]/login

我认为会话不起作用。在我开发我的第一个 PHP 应用程序时,我遇到了类似的基于会话的问题。但事实证明它起作用了。那就是[server]/session/testand[server]/session/print进来的地方。

当我登录并使用Padriono console时,我看到了该条目。HerokuUser.all

我还看到用户通过了身份验证。有些东西必须与`

我检查了Padrino admin Accounts模态。我认为重要的参数是idrole

我做错了什么吗?

提前致谢。非常感谢任何帮助。

4

1 回答 1

0

在浏览了 Padrino 源代码后,我注意到它需要Account该类进行Padrino Admin身份验证。

我假设,我可以制作任何课程并使用它。但是目前,我已经修改了Account.rb模态,而不是使用User( 上面 ) 我使用了Account.

我在解决它时写了这个,所以模态的验证部分被注释掉了。

class Account
  include DataMapper::Resource
  include DataMapper::Validate
  attr_accessor :password, :password_confirmation

  # Properties
  property :id,               Serial
  property :name,             String
  property :surname,          String
  property :email,            String
  property :crypted_password, String, :length => 70
  property :role,             String

  property :uid,              String
  property :display_name,     String
  property :provider,         String

  # # Validations
  # validates_presence_of      :email, :role
  # validates_presence_of      :password,                          :if => :password_required
  # validates_presence_of      :password_confirmation,             :if => :password_required
  # validates_length_of        :password, :min => 4, :max => 40,   :if => :password_required
  # validates_confirmation_of  :password,                          :if => :password_required
  # validates_length_of        :email,    :min => 3, :max => 100
  # validates_uniqueness_of    :email,    :case_sensitive => false
  # validates_format_of        :email,    :with => :email_address
  # validates_format_of        :role,     :with => /[A-Za-z]/

  # Callbacks
  before :save, :encrypt_password

  ##
  # This method is for authentication purpose
  #
  def self.authenticate(email, password)
    account = first(:conditions => ["lower(email) = lower(?)", email]) if email.present?
    account && account.has_password?(password) ? account : nil
  end

  ##
  # This method is used by AuthenticationHelper
  #
  def self.find_by_id(id)
    get(id) rescue nil
  end

  def has_password?(password)
    ::BCrypt::Password.new(crypted_password) == password
  end

  private
  def password_required
    crypted_password.blank? || password.present?
  end

  def encrypt_password
    self.crypted_password = ::BCrypt::Password.create(password) if password.present?
  end
end

请注意,在角色之后,我又添加了 3 个字段,即uid,display_nameprovider.

似乎,uid provder并且role对于访问控制很重要。

controller/route是相同的,除了一个小的变化。那是模型名称。

  if account.nil? 
    # Create account
    account               = Account.new 

Omniauth将自己的模态与and一起使用会很有趣Padrino Admin helpers。但就目前而言,这很棒!

于 2013-09-15T19:24:04.090 回答