2012-04-22 20 views
2

我有一個使用devise進行登錄的應用程序。我在Web應用程序中有一個登錄表單,用於向數據庫驗證用戶身份,並簡單地將@user散列作爲json字符串返回。使用{render json時出現缺失屬性:}

的目標是讓用戶認證用戶並檢索其authentication_token在App將來使用,以防止用戶不必不斷登錄。

的問題是,我不能讓authentication_token到被包含在返回的json中。

我user.rb型號

attr_accessible :authentication_token, :email, :password, :password_confirmation, :remember_me, :bio, :confirmed, :deposit, :email, :fri25, :mon21, :name, :paid, :picture, :sat26, :sun20, :sun27, :thur24, :tue22, :wed23 

明確包括authentication_token符號。

然後在會話控制器中,我有一個名爲newApi的自定義操作,它運行一個簡單的身份驗證方法並以@son散列作爲json作出響應。

def newapi 
@user = User.authenticate(params[:email],params[:password]) 
respond_to do |format| 
    format.json { render json: @user } 
end 

eend

然而不管我做什麼,認證令牌不包含在JSON響應。我錯過了明顯的東西嗎?爲什麼不包括在內?

回答

-1

我結束了使用jbuilder解決自己的問題。

本質上,您只需刪除render json: @user調用並使用jbuilder模板。

在newapi.json.jbuilder

json.(
    @user, 
    :authentication_token, 
    :email, 
    :password, 
    :password_confirmation, 
    :remember_me, 
    :bio, 
    :confirmed, 
    :deposit, 
    :email, 
    :fri25, 
    :mon21, 
    :name, 
    :paid, 
    :picture, 
    :sat26, 
    :sun20, 
    :sun27, 
    :thur24, 
    :tue22, 
    :wed23 
) 

審查他們的文檔,如果你因爲有很多它的得到了這條路線全部都在我需要的多,是我們現在做的API返回的唯一途徑。如果你以前沒有用過它,請查看!它使API端點非常簡單。

尼克·諾德森的回答也是有效的,如果你想推出自己的設置。

+0

解決方案在哪裏? You'e「回答」您自己的問題(未提供解決方案)標記爲正確的問題,甚至沒有投票答案,導致您的解決方案。這真的不是使用Stackoverflow的方式。 – lcguida 2014-09-18 14:24:42

+0

更新的答案提供了一個示例。 – JonathanSimmons 2016-02-01 15:50:00

4

設計> 2.x似乎從xml和json響應中去除屬性。這可能是一項安全功能,但我不確定它是從哪裏推出的。 「保護屬性」 的名單是在這裏:

https://github.com/plataformatec/devise/blob/master/lib/devise/models/authenticatable.rb

線54:

BLACKLIST_FOR_SERIALIZATION = [:encrypted_password, :reset_password_token, :reset_password_sent_at, 
    :remember_created_at, :sign_in_count, :current_sign_in_at, :last_sign_in_at, :current_sign_in_ip, 
    :last_sign_in_ip, :password_salt, :confirmation_token, :confirmed_at, :confirmation_sent_at, 
    :remember_token, :unconfirmed_email, :failed_attempts, :unlock_token, :locked_at, :authentication_token] 

,並初始化它是線122-135

代碼中的註釋說可以提供您自己的列入黑名單的屬性,或者分別使用:force_except:except附加到現有列表。

我哈克的解決辦法是這樣的:

def newapi 
    @user = User.authenticate(params[:email],params[:password]) 
    respond_to do |format| 
    format.json { render json: @user.as_json(:force_except => Devise::Models::Authenticatable::BLACKLIST_FOR_SERIALIZATION.delete_if{|x| x == :authentication_token} } 
    end 
end 

但我想會有某處更優雅覆蓋這個列表就像一個初始化的方法。礦井工程,但可能不是最好的答案。

1

我的解決方法:

class User < ActiveRecord::Base 
    # include devise token_authenticatable and others 
    devise :token_authenticatable 

    # after devise finds our user (such as when logging in) 
    after_find :write_auth_token 

    # write our pseudo attribute to the model 
    def write_auth_token 
    write_attribute(:auth_token, self.authentication_token) 
    end 

    # make our pseudo attribute attr_accessible 
    attr_accessible :auth_token 
end 
0

@Travis託德的回答完全做的工作,是的,有可能是一個更好的解決方案。另外,如果你想建立的數據庫遷移或其他類似用途的私人或臨時API,你需要2個或更多這些黑名單的屬性,你可能想要做這樣的事情:

def newapi 
    @devise_attrs = [:encrypted_password, :remember_created_at, :sign_in_count, :current_sign_in_at] #etc.. 
    @user = User.authenticate(params[:email],params[:password]).includes(:identity) 
    respond_to do |format| 
    # I added a few other options and updated ruby syntax so that you can see how can this be customized if in need of specific user attributes or relations. 
    format.json { render json: @user.as_json(force_except: Devise::Models::Authenticatable::BLACKLIST_FOR_SERIALIZATION.delete_if{|x| @devise_attrs.include?(x)}, include: [:identity]), status: 200 } 
    end 
end 

仍在等待另一個舔手指優雅的解決方案。