简体   繁体   English

类似于自助服务终端的网络应用程序-如何“锁定”该应用程序?

[英]Kiosk-like web application - how do I “lock” the app?

Question: What's a good way to "lock" a Rails web application so a user must enter credentials to unlock it (but such that the user is still logged into the app and simply can't use the app without unlocking it)? 问题:“锁定” Rails Web应用程序的一种好方法是什么,以便用户必须输入凭据才能对其进行解锁(但这样用户仍然登录到该应用程序中,并且无法在未解锁的情况下使用该应用程序)?

What I'm doing 我在做什么

I'm building a task management app that behaves like a kiosk to be used by multiple users. 我正在构建一个行为管理应用程序,其行为类似于供多个用户使用的信息亭。 Users can log in to the app using their email address and password (full credentials), but once they're in, they can "swap" users by selecting their name from a list and entering a four-digit PIN (easy credentials). 用户可以使用其电子邮件地址和密码(完整凭据)登录到该应用程序,但是一旦进入,便可以通过从列表中选择其名称并输入四位数的PIN(简单凭据)来“交换”用户。

Why have two types of credentials? 为什么有两种凭证?

This is a multi-tenant app, and users use "full credentials" to simply get into the app and choose a tenant. 这是一个多租户应用程序,用户使用“完整凭据”即可进入该应用程序并选择一个租户。 Once they're in, they will frequently swap out as new employees come on shift and other employees leave because multiple employees will share a single work station. 一旦进入,随着新员工的轮班和其他员工的离职,他们将频繁调换工作,因为多个员工将共享一个工作站。

Rather than forcing users to repeatedly enter their "full" credentials (by doing a full logout/login), I've created a name/PIN set of credentials they can use to easily swap. 我没有强迫用户反复输入其“完整”凭据(通过执行完整的注销/登录),而是创建了一个名称/ PIN凭据集,可用于轻松交换。 Once they're logged in with full credentials and have chosen their tenant, the app provides an autocomplete list of user's names, so it's very easy to select one's name from the list, enter the PIN and swap users. 一旦他们以完整的凭据登录并选择了他们的租户,该应用程序就会提供用户名的自动完成列表,因此从列表中选择一个人的名字,输入PIN并交换用户非常容易。

Note that this "swapping" functionality is already built and working. 请注意,此“交换”功能已经构建并且可以正常工作。

Why do I need to lock the app? 为什么需要锁定应用程序?

When a user is logged in to the app and a tenant, they may need to leave the app to go do other work. 当用户登录到应用程序和租户时,他们可能需要离开应用程序才能执行其他工作。 Without a lock screen, they only have two choices: fully log out so that the next user has to enter "full" credentials to use the app or just leave their account logged in for anyone to mess with. 没有锁定屏幕,他们只有两种选择:完全注销,以便下一个用户必须输入“完整”凭据才能使用该应用程序,或者仅使他们的帐户登录才能被任何人使用。

I would like to allow them to click a button to "lock" the app when they walk away so that users can leave the app "logged in" without allowing other users to access others' accounts. 我想允许他们在离开时单击按钮以“锁定”该应用程序,以便用户可以使该应用程序“登录”,而不允许其他用户访问其他用户的帐户。 Once they click "lock" all they can do is enter a name/PIN to unlock it, or click "sign out" to fully log out. 一旦他们单击“锁定”,他们所能做的就是输入名称/ PIN码以对其进行解锁,或者单击“退出”以完全注销。

Here's what a typical use-case would look like: 这是典型的用例:

  • Frank logs into the app using his email address and password. Frank使用他的电子邮件地址和密码登录到该应用程序。
  • He completes some tasks. 他完成了一些任务。
  • Jane wants to use the app, so she "swaps in" by choosing her name from a list and entering her four-digit PIN. Jane想要使用该应用程序,因此她通过从列表中选择自己的名字并输入四位数的PIN码来“交换”信息。
  • Now Jane is the logged-in user, meaning she can complete tasks, edit her profile, and other activities. 现在Jane是登录用户,这意味着她可以完成任务,编辑个人资料以及其他活动。
  • Jane completes some tasks and needs to go do something else in the store, so she clicks the "Lock" button on the screen. Jane完成了一些任务,需要在商店中执行其他操作,因此她单击了屏幕上的“锁定”按钮。
  • The app is now locked and requires authentication to use (name and PIN) or the user can click "sign out" to fully go out of the app. 该应用程序现已锁定,需要使用身份验证(名称和PIN),否则用户可以单击“退出”以完全退出该应用程序。 The screen simply says something like "The app is locked. Enter your name and PIN to unlock it." 屏幕上仅显示诸如“该应用已锁定。输入您的姓名和PIN码以对其进行解锁”之类的内容。

The options as I understand them 据我了解的选择

It seems like there are two ways to go here: 看来这里有两种方法:

  1. JavaScript of some kind 某种JavaScript
  2. Some sort of controller logic using session variables or cookies 使用会话变量或cookie的某种控制器逻辑

JavaScript makes me nervous because it's pretty hackable. JavaScript让我感到紧张,因为它很容易被入侵。 I want to make sure the app is actually secure. 我想确保该应用程序实际上是安全的。

So I've been messing with ways of using session variables to do this. 因此,我一直在弄乱使用会话变量执行此操作的方法。 Here is what I've been trying: 这是我一直在尝试的方法:

  • User is authenticated to the app for a particular tenant 用户已通过特定租户的应用程序身份验证
  • User clicks the "Lock" button 用户单击“锁定”按钮
  • A "lock_ui" action is called in the Sessions controller 在Sessions控制器中调用“ lock_ui”操作
  • That action sets a few session variables (session[:locked], session[:locked_by], session[:locked_at]) 该操作设置了一些会话变量(session [:locked],session [:locked_by],session [:locked_at])
  • The app then always redirects to Sessions#locked, which displays the "This is locked. Enter name and PIN to unlock" form unless it's unlocked or the user clicks "sign out". 然后,该应用程序始终重定向到Sessions#locked,显示“已被锁定。输入名称和PIN码以进行解锁”表单,除非该应用程序已解锁或用户单击“退出”。
  • Once a user enters a valid name/PIN, those session variables are deleted and the app functions normally. 用户输入有效的名称/ PIN后,这些会话变量将被删除,并且该应用正常运行。

Any suggestions on how I might do this so that it's secure? 关于如何执行此操作以确保安全的任何建议?

Things I'm hung up on: 我挂断的事情:

  • Should I be using some sort of application controller filter (before or around) to check to see if the app is locked? 我是否应该使用某种应用程序控制器过滤器(之前或前后)来检查应用程序是否被锁定? What does the application controller do if the app is locked? 如果应用程序被锁定,应用程序控制器会做什么? (Does it call some other action, render a the "locked" page directly, or something else?) (它是否调用其他动作,直接呈现“锁定”页面或其他内容?)
  • Or is this something that should be handled in the view layer? 还是这应该在视图层中处理? For example, I could update my application layout so it has an "if locked_ui render the 'locked' screen, else yield". 例如,我可以更新我的应用程序布局,使其具有“如果locked_ui呈现“锁定”屏幕,否则产生”。

Some notes on how I'm currently set up: 关于我目前的设置方式的一些注意事项:

  • This is a Rails 4.1.0 app using Ruby 1.9.3 hosted on heroku. 这是在heroku上使用Ruby 1.9.3的Rails 4.1.0应用程序。
  • I'm using CanCan for authorization 我正在使用CanCan进行授权
  • I'm using multi-tenancy with scopes (and I'm not using sub-domains) 我正在使用具有范围的多租户 (并且我没有使用子域)
  • Each user has only one account that may have access to multiple tenants 每个用户只有一个帐户,可以访问多个租户
  • I've seen JQuery BlockUI , but it seems more like a vanity thing than a functional security device 我看过JQuery BlockUI ,但它似乎更像是虚荣的东西,而不是功能安全的设备。

Here's what I ended up building. 这就是我最终建立的。

To answer my own questions: 要回答我自己的问题:

Should I be using some sort of application controller filter (before or around) to check to see if the app is locked? 我是否应该使用某种应用程序控制器过滤器(之前或前后)来检查应用程序是否被锁定? I am using a before_filter in my Application Controller to check whether the UI is locked. 我在应用程序控制器中使用before_filter检查UI是否已锁定。 If it's locked, I redirect to the "locked" screen. 如果已锁定,我将重定向到“锁定”屏幕。 I then added a skip_before_filter to the relevant actions in my Sessions Controller (essentially ignoring that before_filter when the user is navigating to the "locked" screen and related lock/unlock actions in the Sessions controller. 然后,我在我的Sessions控制器中的相关动作中添加了skip_before_filter(当用户导航到Sessions控制器中的“锁定”屏幕和相关的锁定/解锁动作时,基本上忽略了before_filter。

Or is this something that should be handled in the view layer? 还是这应该在视图层中处理? In the view layer, I mostly just needed to create the actual "locked" screen (where a user enters credentials to unlock the app), and I make sure to hide navigation elements while the UI is locked (so the user isn't confused as to why they click "Edit Profile" and don't leave the lock screen). 在视图层中,我几乎只需要创建实际的“锁定”屏幕(用户输入凭据即可解锁应用程序),并且确保在UI锁定时隐藏导航元素(因此用户不会感到困惑) (为什么他们单击“编辑个人资料”而不离开锁定屏幕)。

I'm using cookies to record the current state of the UI (locked or not). 我正在使用cookie记录UI的当前状态(是否锁定)。 Here are some code snippets: 以下是一些代码段:

application_controller.rb application_controller.rb

before_filter :confirm_unlocked_ui

private

def confirm_unlocked_ui
  if signed_in? && locked_ui?
    redirect_to locked_path
  end
end

sessions_helper.rb sessions_helper.rb

def locked_ui?
  session[:locked] == '1'
end

def lock_ui
  session[:locked] = '1'
  session[:locked_by] = current_user.id
  session[:locked_at] = Time.zone.now
end

def unlock_ui
  session.delete(:locked)
  session.delete(:locked_by)
  session.delete(:locked_at)
end

sessions_controller.rb sessions_controller.rb

def lock
  session[:return_to] = params[:return_to] if params[:return_to]
  lock_ui

  redirect_to locked_path
end

def locked
  #essentially just a view
end

def unlock
  user = User.find_by_id(params[:session][:unlock_user_id]) 
  if user && user.authenticate_with_pin(params[:session][:pin])
    cookies[:auth_token] = user.auth_token
    unlock_ui
    redirect_back_or root_path
  else      
    flash.now[:error] = "Invalid PIN."
    render 'locked'
  end
end

def destroy
  sign_out
  unlock_ui
  redirect_to root_path
end

I really don't know how "good" this solution is, and one reason I'm posting it here is to see if others come up with better ideas or see any issues lurking with how I've done this. 我真的不知道这个解决方案有多“好”,我在这里发布它的一个原因是,看看其他人是否提出了更好的主意,或者发现我如何做到这一点潜伏着任何问题。

Some more subtle things you might want to think about if you're trying this: 如果要尝试此操作,可能需要考虑一些更细微的事情:

  • I'm using CanCan for authorization, and I've left that out here. 我正在使用CanCan进行授权,因此这里省略了。 If you have role-based authorization or something like that, be sure to check that this works for each role. 如果您具有基于角色的授权或类似的授权,请确保检查它是否适用于每个角色。
  • Notice that I allow users to 'sign out' if they don't want to 'unlock'. 请注意,如果用户不想“解锁”,则允许他们“退出”。 I do this using the 'destroy' action my sessions controller and I make sure to 'unlock_ui' before I redirect them after signing out. 我使用会话控制器的“ destroy”操作执行此操作,并且在注销后重定向它们之前,请确保先进行“ unlock_ui”操作。 If I didn't do this, then the app would still be "locked" the next time they log in from that browser. 如果我不这样做,那么下次他们从该浏览器登录时,该应用仍将被“锁定”。
  • locked_path is an alias for Sessions#locked (basically just a view/form) that responds to a get request. locked_pa​​th是Sessions#locked的别名(基本上只是视图/表单),用于响应get请求。
  • Sessions#Lock also responds to get requests. Sessions#Lock也响应以获取请求。
  • Sessions#Unlock is what is called when the form is submitted from the "locked" view. 从“锁定”视图提交表单时,将调用Sessions#Unlock。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何检查在特定端口上运行的Web应用程序? - How do I check the web application running on a specific port? 作为初学者,我如何知道网络应用程序是否安全 - As a beginner how do I know if a web app is secure 如何将heroku上的现有Web应用程序迁移到Rails? - How do I migrate an existing web app on heroku to rails? 如何从 web 应用程序获取桌面通知? - How do I get a desktop notification from a web app? 如何在我的 web 应用程序中显示每个 git 提交? - How do I display every git commits in my web application? 如何为功能类似于本机iOS或Android应用程序的Ruby on Rails应用程序添加后退按钮? - How do I make a back button for a Ruby on Rails app that functions like a native iOS or Android app? 如何锁定表以防止在 Rails 中使用记录创建? - How do I lock a table to prevent record creation using in Rails? 如何为我的应用程序创建Twitter样式的URL-使用现有应用程序或重新设计应用程序-Ruby on Rails - How do I create Twitter style URLs for my app - Using existing application or app redesign - Ruby on Rails 如何在 REST API 中分离移动应用用户和 Web 应用用户? - How do I separate the Mobile app user and web app user in REST API? 我如何锁定数据库,所以什么也不能修改 - How do I lock a database so nothing can be modified
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM