设计每次限制每个用户一个会话

Joh*_*ohn 47 session ruby-on-rails devise ruby-on-rails-3

我的应用程序使用的是Rails 3.0.4和Devise 1.1.7.

我正在寻找一种方法来阻止用户共享帐户,因为该应用程序是基于订阅的服务.我已经搜索了一个多星期,我仍然不知道如何实施解决方案.我希望有人已经实施了一个解决方案,可以指出我正确的方向.

解决方案(谢谢大家的答案和见解!)

在应用程序controller.rb中

before_filter :check_concurrent_session

def check_concurrent_session
  if is_already_logged_in?
    sign_out_and_redirect(current_user)
  end
end

def is_already_logged_in?
  current_user && !(session[:token] == current_user.login_token)
end
Run Code Online (Sandbox Code Playgroud)

在session_controller中重写Devise Sessions控制器:

skip_before_filter :check_concurrent_session

def create
  super
  set_login_token
end

private
def set_login_token
  token = Devise.friendly_token
  session[:token] = token
  current_user.login_token = token
  current_user.save
end
Run Code Online (Sandbox Code Playgroud)

在迁移AddLoginTokenToUsers

def self.up
  change_table "users" do |t|
    t.string "login_token"
  end
end

def self.down
  change_table "users" do |t|
    t.remove "login_token"
  end
end
Run Code Online (Sandbox Code Playgroud)

sca*_*er2 31

这个宝石效果很好:https://github.com/devise-security/devise-security

添加到Gemfile

gem 'devise-security'
Run Code Online (Sandbox Code Playgroud)

捆绑安装后

rails generate devise_security:install
Run Code Online (Sandbox Code Playgroud)

然后跑

rails g migration AddSessionLimitableToUsers unique_session_id
Run Code Online (Sandbox Code Playgroud)

编辑迁移文件

class AddSessionLimitableToUsers < ActiveRecord::Migration
  def change
    add_column :users, :unique_session_id, :string, limit: 20
  end
end
Run Code Online (Sandbox Code Playgroud)

然后跑

rake db:migrate
Run Code Online (Sandbox Code Playgroud)

编辑您的app/models/user.rb文件

class User < ActiveRecord::Base
  devise :session_limitable # other devise options
  ... rest of file ...
end
Run Code Online (Sandbox Code Playgroud)

完成.现在从另一个浏览器登录将杀死任何以前的会话.gem实际通知用户他将在登录前杀死当前会话.


fl0*_*00r 10

你不能这样做.

  • 您可以控制用户的IP地址,这样您就可以防止用户同时存在两个IP.您可以绑定登录和IP.您可以尝试通过IP检查城市和其他地理位置数据以阻止用户.
  • 您可以设置cookie来控制其他内容.

但这一切都不能保证只有一个用户使用此登录,并且来自世界各地的那些105 IP不仅属于一个使用Proxy或其他任何用户的唯一用户.

最后一点:你永远不需要在互联网上.

UPD

但是,我要问的是限制多个用户同时使用同一个帐户,我觉得应该可以

因此,您可以存储一些令牌,其中包含一些加密数据:IP +秘密字符串+用户代理+用户浏览器版本+用户操作系统+任何其他个人信息:encrypt(IP + "some secret string" + request.user_agent + ...).然后,您可以使用该令牌设置会话或cookie.并且每个请求都可以获取它:如果用户是相同的?他是否在同一操作系统等中使用相同的浏览器和相同的浏览器版本

您还可以使用动态令牌:您可以更改每个请求的令牌,因此每个会话只能有一个用户使用系统,因为每个请求令牌都将被更改,另一个用户将被注销,只要他的令牌将过期.

  • 你永远做不到==你可以做到.在这里双重否定. (7认同)