【譯】不依賴于Devise模塊如何實現(xiàn)簡單的驗證功能

幾乎每一個web應(yīng)用都需要表格登錄座柱。在Ruby中,最流行的選擇就是在Rails應(yīng)用中實用Devise模塊输吏。

Devise提供了許多盒子之外的功能权旷,但這也同樣是令人沮喪的地方。它有很多的“魔法”贯溅,并且和Rails的很多功能高度耦合拄氯。但是如果你的需求和這個gem并不是很切合躲查,舉例說,匿名用戶-你將需要翻閱整個文檔并且閱讀源碼译柏,來查詢?nèi)绾螌崿F(xiàn)它踩晶。這一點也不可愛逃延,并且看上去一點也不值。如果未來的一段時間內(nèi)有驗證需求的改變,這個改變對你來說看起來容易實現(xiàn)還是一場噩夢淘衙?

驗證事實上是非常簡單的!如果你的需求足夠簡單债蓝,你將可以在100行代碼以內(nèi)實現(xiàn)你的驗證功能耗美。在這片文章中,我將給你展示一個小而美的包含登錄盟劫,登出和用戶創(chuàng)建的小的web應(yīng)用夜牡。

所有的源碼都可以在這里找到:
simple_authentication.rb

依賴###

唯一的依賴就是用于創(chuàng)建密碼的BCrypt gem。我們可以直接使用它侣签,在Rails和Devise中都已經(jīng)默認(rèn)包含了塘装。

在本例中,我們將使用Sinatra影所,由于BCrypt 解藕起來非常容易蹦肴,因此代碼可以輕松地翻譯成Rails,這跟Devise很不一樣猴娩。

Gemfile:

source 'https://rubygems.org'
gem 'sinatra', '~>1.4'
gem 'bcrypt', '~>3.1'

BCrypt實現(xiàn)哈希密碼###

需要大約兩行代碼來實現(xiàn)這個需求:

def hash_password(password)
   BCrypt::Password.create(password).to_s
end

def test_password(password, hash)
  BCrypt::Password.new(hash) == password
end

hash_password函數(shù)生成了一個普通文本密碼阴幌,由單向加密算法加密。要想基于哈希來破解密碼卷中,是一件很困難的矛双、幾乎不可能實現(xiàn)的事情。我們從不存儲密碼蟆豫,只有哈希议忽。所以,當(dāng)有黑客進(jìn)入數(shù)據(jù)庫的事情發(fā)生十减,我們的密碼依然是手保護(hù)的栈幸。

test_password函數(shù)用于檢測當(dāng)給定的密碼是否和之前函數(shù)給出的hash一致。由于我們不在擁有原始密碼帮辟,所以這次通過給定密碼的hash和之前的hash相比較速址。

這是基本的密碼安全,而這所有的工作都交由bcrypt gem來實現(xiàn)织阅。

User Model###

為了讓本例看起來足夠簡單壳繁,User模型只是一個Struct,而“數(shù)據(jù)庫”就是一個數(shù)組。

User = Struct.new(:id, :username, :password_hash)
USERS = [
    User.new(1,'Bob',hash_password('The building'))
    User.new(2, 'Sally', hash_password('go round'))
]

每個用戶都只有三個基本屬性:id闹炉,username蒿赢,hash。如果這是在Rails當(dāng)中渣触,你可以創(chuàng)建一個只有這三個屬性的模型羡棵。

Signing In###

下列代碼運行于用戶提交登錄表格:

post '/sign_in' do
   user = USERS.find{ |u| u.username == params[:username]}
    if user && test_password(params[:password],user.password_hash)
        session.clear
        session[:user_id] = user.id
        redirect '/'
     else
        @error = 'Username or password was incorrect'
        erb :sign_in
     end
end

安全須知:一旦成功登錄,我們在存儲用戶名之前情調(diào)session嗅钻,這是一種阻止Session Fixation Attacks的安全策略

訪問當(dāng)前用戶###

一旦用戶登入皂冰,我們需要知道未來誰來在發(fā)送請求。下述代碼可以返回當(dāng)前用戶:

    def current_user
        if session[:user_id]
          USERS.find { |u| u.id == session[:user_id] }
        else
           nil
         end
      end

當(dāng)我們在登入狀態(tài)時养篓,檢查session是否包含user id秃流,當(dāng)user id存在時,根據(jù)用戶id找到user柳弄。如果是在Rails當(dāng)中舶胀,又可以用User.find(session[:user_id]).

在主頁中,我們可以使用current_user:

<p>Hello, <%= current_user.username %></p>

Signing Out###

如下:

post '/sign_out' do
    session.clear
    redirect '/sign_in'
end

由于用戶id存儲在session中碧注,我們只需要清除session來sign out嚣伐。簡單而又優(yōu)美!

創(chuàng)建一個新用戶###

代碼如下:

post '/create_user' do
    USERS << User.new(
        USERS.size + 1,
        params[:username],
        hash_password(params[:password])
    )
    redirect '/'
end

在這個小小的實例中萍丐,我們創(chuàng)建了一個User對象轩端,并將它添加到user數(shù)組中。

結(jié)束語###

擁有一個基本驗證的工作實例一點也不難逝变,不是嗎基茵?

原文How To Implement Simple Authentication Without Devise

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市壳影,隨后出現(xiàn)的幾起案子耿导,更是在濱河造成了極大的恐慌,老刑警劉巖态贤,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異醋火,居然都是意外死亡悠汽,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門芥驳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來柿冲,“玉大人,你說我怎么就攤上這事兆旬〖俪” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長宿饱。 經(jīng)常有香客問我熏瞄,道長,這世上最難降的妖魔是什么谬以? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任强饮,我火速辦了婚禮,結(jié)果婚禮上为黎,老公的妹妹穿的比我還像新娘邮丰。我一直安慰自己,他們只是感情好铭乾,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布剪廉。 她就那樣靜靜地躺著,像睡著了一般炕檩。 火紅的嫁衣襯著肌膚如雪斗蒋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天捧书,我揣著相機與錄音吹泡,去河邊找鬼。 笑死经瓷,一個胖子當(dāng)著我的面吹牛爆哑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播舆吮,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼揭朝,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了色冀?” 一聲冷哼從身側(cè)響起潭袱,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎锋恬,沒想到半個月后屯换,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡与学,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年彤悔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片索守。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡晕窑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出卵佛,到底是詐尸還是另有隱情杨赤,我是刑警寧澤敞斋,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站疾牲,受9級特大地震影響植捎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜说敏,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一鸥跟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧盔沫,春花似錦医咨、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至谴忧,卻和暖如春很泊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背沾谓。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工委造, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人均驶。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓昏兆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親妇穴。 傳聞我的和親對象是個殘疾皇子爬虱,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1.caching with instance variables2.dynamic find_by method...
    Jayzen閱讀 1,376評論 0 1
  • devise是一個很好的用戶登錄gem。但還是想自己寫個“輪子”腾它,一則本來就是在學(xué)習(xí)rails跑筝,二則是了解了用戶登...
    kamionayuki閱讀 6,254評論 2 9
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法瞒滴,內(nèi)部類的語法曲梗,繼承相關(guān)的語法,異常的語法妓忍,線程的語...
    子非魚_t_閱讀 31,639評論 18 399
  • 1.Environment Variables [finish] 2.Ruby Version Managers ...
    Jayzen閱讀 1,255評論 0 1
  • 準(zhǔn)備工具 ruby v2.2.6rails v5.0.0.1 開整 新建項目 rails new blog 進(jìn)入目...
    ahtest閱讀 1,387評論 0 3