【问题标题】:Rails + iOS authentication without devise无需设计的 Rails + iOS 身份验证
【发布时间】:2014-08-31 23:20:42
【问题描述】:

我有一个非常简单的 Rails 应用程序,我根据 Michael Hartl (http://www.railstutorial.org/book/modeling_users) 的 rails 教程书推出了自己的身份验证。该应用程序是一个内容管理系统,适用于同样简单的 iOS 应用程序。我知道设计很受欢迎,但我真的认为这个项目没有必要。我希望能够将我的 iOS 应用程序链接到我的 Rails 应用程序,但无论在哪里,我都能找到的唯一建议是如何使用设计来做到这一点。我想要做的就是让用户看到一个登录屏幕,这样他们就可以建立一个会话,然后我可以处理所有在 Rails 端的权限逻辑。这里有几件事可以让您了解我当前的身份验证方案:

我的会话控制器:

class SessionsController < ApplicationController
  def new
  end

  ##
  #Use the email in the nested hash to find the right user
  #Check to make sure that the user authenticates with the given password
  ##
  def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      sign_in user
      redirect_back_or root_url
    else
      flash.now[:error] = 'Invalid email/password combination'
      render 'new'
    end
  end

  def destroy
    current_user.update_attribute(:remember_token,User.digest(User.new_remember_token))
    cookies.delete(:remember_token)
    self.current_user = nil
    session.delete(:return_to) #not sure if this should really be here or if better way to fix bug
    redirect_and_alert(root_url, "User Successfully Logged Out!",:success)
  end

end

会话助手:

module SessionsHelper
  ##
  #set the remember token for the user
  #make the cookie reflect that token
  #update the users remember token column
  #set the user being passed in as the current user
  ##
  def sign_in(user)
    remember_token = User.new_remember_token
    cookies.permanent[:remember_token] = remember_token
    user.update_attribute(:remember_token, User.digest(remember_token))
    self.current_user = user
  end

  #set the current user
  def current_user=(user)
    @current_user = user
  end

  #Helper current user method
  def current_user
    remember_token = User.digest(cookies[:remember_token])
    @current_user ||= User.find_by(remember_token: remember_token)
  end

  #Is the requesting user the current user
  def current_user?(user)
    user == current_user
  end

  #Is the user signed in?
  def signed_in?
    !current_user.nil?
  end

  #Store user request info for friendly forwarding
  def redirect_back_or(default)
    redirect_to(session[:return_to] || default)
    session.delete(:return_to)
  end

  #Store user request info for friendly forwarding
  def store_location
    session[:return_to] = request.url if request.get?
  end

  #Authorization
  def signed_in_user
    store_location
    redirect_to signin_url, notice: "Please sign in." unless signed_in?
  end

  def super_user
   redirect_and_alert(root_url,
                      "You are not allowed to do that. Contact the admin for this account.",
                      :error) unless (current_user.role.id == 1)
  end

  def super_user_or_admin
    redirect_and_alert(root_url,
                       "You are not allowed to do that. Contact the admin for this account.",
                       :error) unless (current_user.role.id == 1 || current_user.role.id == 2)
  end

  def is_super_user
    current_user.role.id == 1
  end

  def is_admin
    current_user.role.id == 2
  end

  def is_regular_user
    current_user.role.id == 3
  end
end

【问题讨论】:

    标签: ios ruby-on-rails authentication devise


    【解决方案1】:

    您可以选择基于令牌的系统,而不是基于会话的系统。

    为每个用户创建一个名为身份验证令牌的属性。此令牌可以在注册期间生成和分配。令牌本身可以使用简单的技术生成,例如SecureRandom.hex(n),其中n 是生成的随机十六进制数的长度。

    从应用程序登录/注册后,在服务器的响应中发送身份验证令牌。然后,您可以让 iOS 应用将令牌与每个后续请求一起发送到服务器。

    每次控制器收到请求时,让服务器检查令牌。这可以使用before_filter 来实现。因此示例控制器可能如下所示:

        before_filter :authenticate_user
    
        def authenticate_user
          # assuming the parameter sent from the app is called auth_token
          auth_token = params[:auth_token]
          user = User.find_by_authentication_token(auth_token)
    
          if user.nil?
            # what to do if user does not exist
          else
            # what to do if user exists
          end
        end
    

    【讨论】:

      【解决方案2】:

      对于移动应用程序,通常使用令牌而不是会话。令牌本质上只是一个字符串,Rails 应用程序将提供给每个移动设备以验证它是否具有访问权限。

      1. 第 1 步是让您的移动应用针对 Rails 应用进行身份验证(这可以通过自定义电子邮件/密码登录或通过 Facebook 等第三方)。
      2. 让您的 Rails 应用程序向移动应用程序发送令牌
      3. 将此令牌存储在 iOS 上的 UserDefaults 中(帮助链接:http://www.learnswiftonline.com/objective-c-to-swift-guides/nsuserdefaults-swift/
      4. 每当您的应用向 Rails 应用发出请求(或 websocket 连接等)时,发送令牌(通常作为标头)。
      5. 每当 iOS 应用程序打开时,检查 UserDefaults 中的令牌。如果它在那里,那么您将跳过让用户再次进行身份验证。
      6. 如果您想要真正花哨,Rails 应用程序应该只接受一次令牌并在每次请求时发出新令牌。因此,您的 iOS 应用程序会在每个请求上发送一个令牌,然后在每个响应中获取一个新令牌。这是一种更安全的做法,因此不会有人抢到令牌并弄乱您的 Rails 应用程序。

      此图涵盖了高级流程(它使用 FB 登录进行初始身份验证,但您可以插入您的/替代系统):http://www.eggie5.com/57-ios-rails-oauth-flow

      【讨论】:

        猜你喜欢
        • 2012-02-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-27
        • 1970-01-01
        • 2011-07-23
        • 1970-01-01
        相关资源
        最近更新 更多