加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby – Meteor使用bcrypt从其他服务器验证电子邮件/密码

发布时间:2020-12-17 02:25:37 所属栏目:百科 来源:网络整理
导读:我想让我的meteor用户通过 ruby应用程序登录. 我在哪里 我有两个网站,都在同一个域上,都共享相同的MongoDB. 一个是具有帐户密码的METEOR应用程序(使用bcrypt) 另一个是RUBY ON RAILS-app,它使用devise(也使用bcrypt)进行身份验证. 在这两个应用程序上,我可以
我想让我的meteor用户通过 ruby应用程序登录.

我在哪里

>我有两个网站,都在同一个域上,都共享相同的MongoDB.
>一个是具有帐户密码的METEOR应用程序(使用bcrypt)
>另一个是RUBY ON RAILS-app,它使用devise(也使用bcrypt)进行身份验证.
>在这两个应用程序上,我可以单独注册和登录.

当我将来自Meteor的“bcrypt”字段的encrypted_pa??ssword传输(复制/粘贴)到Ruby的“encrypted_pa??ssword”并尝试登录时,我被拒绝了.它不起作用反之亦然.然后我在我的ruby应用程序中重新创建了流星应用程序的salting(SHA-256 plain-password-hashing,然后才进行比较).

(这里是meteor accounts-password源文件(https://github.com/meteor/meteor/blob/oplog-backlog-on-1.0.3.1/packages/accounts-password/password_server.js))

这是我的Ruby实现:

class BCryptSHA256Hasher < Hasher
  def initialize
    @algorithm = :bcrypt_sha256
    @cost = 10
    @digest = OpenSSL::Digest::SHA256.new
  end

  def salt
    BCrypt::Engine.generate_salt(@cost)
  end

  def get_password_string(password)
    @digest.digest(password) unless @digest.nil?
  end

  def encode(password,salt)
    password = get_password_string(password)
    hash = BCrypt::Engine.hash_secret(password,salt)
    return hash
  end

  def verify(password,encoded)
    password_digest = get_password_string(password)
    hash = BCrypt::Engine.hash_secret(password_digest,encoded)
    # password = "asdfasdf"
    # encoded  = "$2a$10$FqvtI7zNgmdWJJG1n9JwZewVYrzEn38JIxEGwmMviMsZsrCmYHqWm"
    # hash     = "$2a$10$FqvtI7zNgmdWJJG1n9JwZe22XU1hRDSNtHIrnYve9FbmjjqJCLhZi"
    # constant_time_comparison:
    constant_time_compare(encoded,hash)
  end

  def constant_time_compare(a,b)
    check = a.bytesize ^ b.bytesize
    a.bytes.zip(b.bytes) { |x,y| check |= x ^ y }
    check == 0
  end

end

这是一个有效的用户文档,将由两个服务器使用:

{
  "_id": "g4BPfpavJGGTNgJcE","authentication_token": "iZqmCsYS1Y9Xxh6t22-X","confirmed_at": new Date(1457963598783),"createdAt": new Date(1457963456581),"current_sign_in_at": new Date(1457966356123),"current_sign_in_ip": "127.0.0.1","email": "demo@demo.com","emails": [
    {
      "address": "demo@demo.com","verified": true
    }
  ],"encrypted_password": "$2a$10$7/PJw51HgXfzYJWpaBHGj.QoRCTl0E29X0ZYTZPQhLRo69DGi8Xou","failed_attempts": 0,"last_sign_in_at": new Date(1457966356123),"last_sign_in_ip": "127.0.0.1","profile": {
    "_id": ObjectId("56e6c1e7a54d7595e099da27"),"firstName": "asdf","lastName": "asdf"
  },"reset_password_sent_at": null,"reset_password_token": null,"services": {
    "_id": ObjectId("56e6c1e7a54d7595e099da28"),"password": {
      "bcrypt": "$2a$10$7/PJw51HgXfzYJWpaBHGj.QoRCTl0E29X0ZYTZPQhLRo69DGi8Xou"
    },"resume": {
      "loginTokens": [

      ]
    }
  },"sign_in_count": 1,"updated_at": new Date(1457966356127),"username": "mediatainment"
}

解决方法

我认为@ maxpleaner的评论是处理身份验证的最佳方式.但如果真的需要单独验证用户,那么只需要猴子补丁设计.

配置/初始化/ devise_meteor_adapter.rb

module DeviseMeteorAdapter
  def digest(klass,password)
    klass.pepper = nil
    password = ::Digest::SHA256.hexdigest(password)
    super
  end

  def compare(klass,hashed_password,password)
    klass.pepper = nil
    password = ::Digest::SHA256.hexdigest(password)
    super
  end
end

Devise::Encryptor.singleton_class.prepend(DeviseMeteorAdapter)

警告:未经测试.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读