2011-07-10 37 views
6

Tôi đang cố gắng xây dựng hệ thống "chỉ cần nhấp vào tên của bạn để đăng nhập" bằng cách sử dụng auth_logic. Mô hình người dùng của tôi có trường email và tên. Để đăng nhập, tôi chỉ cần làm:# <UserSession: {:author_record => "<protected>"}>

UserSession.create(@user, true) 

Thật không may là không tạo ra phiên. Sử dụng một trình gỡ lỗi tôi thấy tin nhắn này:

#<UserSession: {:unauthorized_record=>"<protected>"}> 

mô hình người dùng của tôi chỉ có một dòng:

acts_as_authentic 

dòng phiên Người dùng có này, mà tôi tìm thấy ở đâu đó. Tôi không chắc chắn những gì nó làm và tôi đã cố gắng có và không có:

class UserSession < Authlogic::Session::Base 
    def to_key 
    new_record? ? nil : [ self.send(self.class.primary_key) ] 
    end 
end 

Cơ sở dữ liệu (Tôi cũng không chắc chắn nếu đó bảng user_sessions là cần thiết):

create_table "sessions", :force => true do |t| 
    t.string "session_id", :null => false 
    t.text  "data" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
end 

add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id" 
add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at" 

create_table "user_sessions", :force => true do |t| 
    t.datetime "created_at" 
    t.datetime "updated_at" 
end 

create_table "users", :force => true do |t| 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    t.string "persistence_token" 
    t.string "email" 
    t.string "name" 
end 

tôi tôi đang sử dụng Rails 3.0.9 và Gemfile tôi nói (tôi đã thử cả hai bình thường và authlogic đá quý Github):

gem 'rails', '3.0.9' 
gem 'sqlite3' 
gem "authlogic" #, :git => 'git://github.com/odorcicd/authlogic.git', :branch => 'rails3' 

Here 's phần còn lại của mã nguồn.

Tôi đã gặp sự cố này vài ngày trước về một dự án tương tự và nó "vừa biến mất" tại một thời điểm nào đó. Tôi chỉ không nhớ làm thế nào.

Bất kỳ ý tưởng nào? Đây là lái xe cho tôi hạt ...

+0

Hi Sjors, tôi đang gặp vấn đề tương tự. Bạn có tìm thấy giải pháp cho vấn đề này không? – Dorian

+0

@dorian nếu bạn chỉ cần đăng nhập Twitter, đá quý này làm cho nó tầm thường: https://github.com/mislav/twitter-login –

+0

Có cùng một vấn đề là tốt. Bất kì giải pháp nào? –

Trả lời

2

Giải pháp có thể xảy ra ... có vẻ như có hai phiên bản của những ví dụ về phương thức trợ giúp này nổi xung quanh. Có là one mà chúng ta sử dụng:

@current_user = current_user_session && current_user_session.user 

và sau đó là the newer version đó là trong một số hướng dẫn mới và các ví dụ:

@current_user = current_user_session && current_user_session.record 

Rõ ràng, khi .user (hoặc bất kỳ lĩnh vực đăng nhập là) được được gọi trên đối tượng session, nó trả về bait_record, trong khi .record.user trả về dữ liệu thích hợp.

+0

Cảm ơn, tôi đã chuyển sang sử dụng đá quý đăng nhập twitter một thời gian trước đây, vì vậy tôi không thể kiểm tra giải pháp của bạn. Tôi chắc chắn nó sẽ giúp đỡ cho một ai đó mặc dù. –

1

Tôi đã gặp sự cố này gần đây và cũng bị nhầm lẫn. Tôi đã tìm ra vấn đề cụ thể của mã của tôi vì vậy đây là một giải pháp tiềm năng khác.

tl; dr

Tôi không hiểu rằng #<UserSession: {:unauthorized_record=>"<protected>"}> vẫn là phiên người dùng hợp lệ, chỉ là một unauthed mà chúng tôi tạo ra chúng ta. Bạn có thể xác nhận điều này bằng cách gọi số user trên đó và bạn sẽ nhận được bất kỳ trường hợp nào User mà bạn đã chuyển vào UserSession.create.

Nguyên nhân

Vấn đề thực tế là hai lần. Phương pháp current_user được xây dựng với giả định rằng người dùng hiện tại sẽ không thay đổi trong suốt thời gian yêu cầu Tôi đã gọi số current_user trước khi tạo một tài khoản để đảm bảo rằng tôi chưa có.Nó có thể được đơn giản hóa như sau:

def current_user 
    return @current_user if defined?(@current_user) 

    @current_user = some_method_that_finds_a_proper_user 
end 

Chìa khóa ở đây là phương pháp của tôi để tìm người dùng có thể trả về nil. Khi đó, nó sẽ xác định @current_usernil và do đó giá trị được lưu trong bộ nhớ cache sẽ luôn được trả về trong các cuộc gọi tiếp theo.

Giải pháp

Đây là nơi khó khăn hơn vì nó thực sự phụ thuộc vào mã của bạn cần.

  1. Nếu bạn không cần current_user sau khi ký một mô hình người dùng với UserSession.create sau đó bạn không cần phải làm bất cứ điều gì nhưng chờ render hoặc chuyển hướng. Trong yêu cầu tiếp theo, current_user của bạn sẽ được đặt chính xác.

  2. Nếu bạn không cần phải kiểm tra cho một đã đăng nhập của người dùng, loại bỏ bất kỳ cuộc gọi đến current_user trước UserSession.create nếu có khả năng và cuộc gọi đầu tiên của bạn để current_user sẽ làm việc như mong đợi.

  3. Đảm bảo chuỗi phương thức của bạn tạo ra current_user hoặc không sử dụng bộ nhớ đệm, không cache nil s hoặc thay đổi bảo vệ cho các giá trị được lưu trong bộ nhớ cache này để xác định xem giá trị có đúng không thay vì nếu biến cá thể được xác định. Người bảo vệ có thể được thay đổi thành:

    return @current_user if [email protected]_user.nil? # or @current_user.present? in Rails 
    

    Hoặc bạn có thể sử dụng toán tử ||= của Ruby và trả lại tiềm ẩn. ví dụ đơn giản của tôi ở trên có thể thay thế:

    def current_user 
        @current_user ||= some_method_that_finds_a_proper_user 
    end 
    

    hoặc nếu nó không phải là đơn giản

    def current_user 
        @current_user ||= begin 
        some_code 
        doing_many 
        things_here 
        end 
    end 
    
  4. Hoặc vấn đề của bạn có thể là bạn đang gặp sự cố viết một bài kiểm tra cho hành vi này. Trong trường hợp đó tôi chỉ muốn đưa một kỳ vọng vào các mã như

    expect(UserSession).to receive(:create).with(user) 
    
Các vấn đề liên quan