简体   繁体   中英

Rails - has_secure_password with password AND PIN - password_digest limitation

I want to have two layers of authentication - I'll call them "hard" and "soft" authentication. The hard layer is the standard email-and-password layer. I've currently implemented this using has_secure_password and the bcrypt-ruby gem as described in this Railscast: #250 Authentication from Scratch (revised) .

For the "soft" layer, I want each user to have a 4-digit PIN that they can use to verify their identity and switch them in as the active user. I would like this PIN to be encrypted just like the password.

My question

How do I have these two layers of authentication using has_secure_password given that it has a "password_digest" column dependency (that doesn't seem customizable or expandable)? I would like to create a "pin_digest" column on the Users table, and just treat it like another password, but it seems has_secure_password doesn't support this.

I'm also curious if anyone has any suggestions for how I might actually implement this, or if it seems like a bad idea for some reason.

Why am I trying to do this?

I'm writing an app that's for a shared kiosk, and I want to make it as easy as possible for users to switch out without having to enter their full login credentials every time. This will be used in a retail store environment where people are moving quickly, and entering a full email address and password every time they switch could be cumbersome and slow.

I'm open to suggestions and approaches if anyone has any good ideas. :)

What it looks like in practice

  • A user logs in using "hard" authentication.
  • Once a user is logged in using "hard" authentication, other users can swap by simply selecting themselves from a list of users and entering their PIN.
  • Users can swap using their PIN as often as they like.
  • Once someone clicks the "hard" logout button, then all users are logged out and "hard" authentication must be used to log back in.

An example

  • Frank gets to work and logs in (using "hard" authentication - entering an email address and password) to a shared kiosk.
  • Frank does some work on the kiosk.
  • Joe gets to work and also needs to use the kiosk.
  • Joe clicks his name on a list of users, then is prompted for his 4-digit PIN ("soft" authentication), which he enters.
  • Frank is no longer the active user.
  • Joe is now the active user.
  • Joe does some work for a while before Frank needs to use the kiosk again.
  • Frank clicks his name from a list of users, then is prompted for his 4-digit PIN, which he enters.
  • When Frank is done, he clicks the "Log out" button. The next person who wants to use the kiosk must log in using "hard" authentication.

I'm trying to do something similar. What I'm going with so far is to compare the entered PIN with the PIN of the person they're claiming to be. So, the form looks sort of like:

<%= form_for SoftSession.new do |f| %>
  <%= f.hidden_field :person_id, value: person.id %>

  <%= f.label(:pin, "PIN") %>
  <%= f.text_field :pin %>

  <%= f.submit %>
<% end %>

and the controller looks like:

pin = params[:soft_session][:pin]
person = Person.find(params[:soft_session][:person_id])

if pin == Person.pin
  # go ahead and do stuff!
else
 # nope.
end

I don't have any idea how secure this is, but maybe it's ok for this purpose.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM