【译】不依赖于Devise模块如何实现简单的验证功能

几乎每一个web应用都需要表格登录。在Ruby中,最流行的选择就是在Rails应用中实用Devise模块。

Devise提供了许多盒子之外的功能,但这也同样是令人沮丧的地方。它有很多的“魔法”,并且和Rails的很多功能高度耦合。但是如果你的需求和这个gem并不是很切合,举例说,匿名用户-你将需要翻阅整个文档并且阅读源码,来查询如何实现它。这一点也不可爱,并且看上去一点也不值。如果未来的一段时间内有验证需求的改变,这个改变对你来说看起来容易实现还是一场噩梦?

验证事实上是非常简单的!如果你的需求足够简单,你将可以在100行代码以内实现你的验证功能。在这片文章中,我将给你展示一个小而美的包含登录,登出和用户创建的小的web应用。

所有的源码都可以在这里找到:
simple_authentication.rb

依赖###

唯一的依赖就是用于创建密码的BCrypt gem。我们可以直接使用它,在Rails和Devise中都已经默认包含了。

在本例中,我们将使用Sinatra,由于BCrypt 解藕起来非常容易,因此代码可以轻松地翻译成Rails,这跟Devise很不一样。

Gemfile:

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

BCrypt实现哈希密码###

需要大约两行代码来实现这个需求:

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

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

hash_password函数生成了一个普通文本密码,由单向加密算法加密。要想基于哈希来破解密码,是一件很困难的、几乎不可能实现的事情。我们从不存储密码,只有哈希。所以,当有黑客进入数据库的事情发生,我们的密码依然是手保护的。

test_password函数用于检测当给定的密码是否和之前函数给出的hash一致。由于我们不在拥有原始密码,所以这次通过给定密码的hash和之前的hash相比较。

这是基本的密码安全,而这所有的工作都交由bcrypt gem来实现。

User Model###

为了让本例看起来足够简单,User模型只是一个Struct,而“数据库”就是一个数组。

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当中,你可以创建一个只有这三个属性的模型。

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

安全须知:一旦成功登录,我们在存储用户名之前情调session,这是一种阻止Session Fixation Attacks的安全策略

访问当前用户###

一旦用户登入,我们需要知道未来谁来在发送请求。下述代码可以返回当前用户:

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

当我们在登入状态时,检查session是否包含user id,当user id存在时,根据用户id找到user。如果是在Rails当中,又可以用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。简单而又优美!

创建一个新用户###

代码如下:

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

在这个小小的实例中,我们创建了一个User对象,并将它添加到user数组中。

结束语###

拥有一个基本验证的工作实例一点也不难,不是吗?

原文How To Implement Simple Authentication Without Devise

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容

  • 1.caching with instance variables2.dynamic find_by method...
    Jayzen阅读 1,357评论 0 1
  • devise是一个很好的用户登录gem。但还是想自己写个“轮子”,一则本来就是在学习rails,二则是了解了用户登...
    kamionayuki阅读 6,233评论 2 9
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,560评论 18 399
  • 1.Environment Variables [finish] 2.Ruby Version Managers ...
    Jayzen阅读 1,238评论 0 1
  • 准备工具 ruby v2.2.6rails v5.0.0.1 开整 新建项目 rails new blog 进入目...
    ahtest阅读 1,374评论 0 3