4

Sinatra を使用して API を構築しています。これは、リクエストを送信するクライアント アプリのユーザー ログイン セッションを管理できるはずです。これまでのところ (ログイン機能のために) 私が得たのは /login のルートであり、ユーザー資格情報が有効であれば、RDBMS で AccessToken が作成されます。下記参照:

    #
    # Login
    #
    post '/login' do
      if (@input["email"].nil? || @input["password"].nil?) then
        response = {
          "success" => false,
          "msg" => "Email and password must be provided"
        }
        $log.error "Email or password not sent to /login"
        return response.to_json
      end

      email     = @input["email"]
      password  = Digest::SHA2.hexdigest(@input["password"])

      user = User.where(:email => email, :password => password).first
      if user.nil?
        response = {
          "success" => false,
          "msg" => "No users exist with that email/password combo"
        }
        $log.error "Invalid Email or Password sent to /login"
        return response.to_json
      end

      token = AccessToken.new(:user_id => user.id)
      token.save!

      $log.info "User valid. Logged in. Token: #{token.token}"
      response = {
        "success" => true,
        "msg" => "User logged in",
        "data" => {"token" => token.token}
      }
      return response.to_json
    end

次に、認証が必要な他のルートについては、トークンがリクエストのパラメーターとして送信されているかどうかを確認しています。

    #
    # Return Clients for User
    #
    # get '/clients/:token' do
    get '/clients' do
      token = AccessToken.where(:token => params[:token]).first
      @current_user = User.find(token.user_id) unless token.nil?

      if @current_user.nil?
        response = {
          "success" => false,
          "msg" => "User must be logged in to do this"
        }
        $log.error "User is not logged in"
        return response.to_json
      end

      response = {
        "success" => true,
        "msg" => "Clients successfully retrieved",
        "data" => {"clients" => @current_user.clients}
      }
      $log.info "Clients successfully retrieved"
      return response.to_json
    end

だから私は疑問に思っています:(a)これはAPIを使用してユーザーセッションを処理するための優れた/堅牢な方法であり、(b)クライアント側(iOS、Android、およびWebアプリ)でそれを処理する標準的な方法はありますか? おそらくアクセストークンをセッション変数に保存し、リクエストごとに送信されるパラメーターにトークンを追加する必要がありますか?

ありがとう!

4

1 に答える 1

1

トークンを交換する標準化された方法については、JSON Web トークンを調べてください: http://jwt.io/

Sinatra の部分については、次のパターンを使用して、認証コードを繰り返さないようにすることができます。

before do
  token = AccessToken.where(:token => params[:token]).first
  @current_user = User.find(token.user_id) unless token.nil?
end

認証方法を登録します。

register do
  def auth (type)
    condition do
      return {
        "success" => false,
        "msg" => "User must be logged in to do this"
      }.to_json unless @current_user
    end
  end
end

これで、この要件を任意のルートに追加できます。

get '/clients', :auth => :user do
  # Your implementation
end
于 2015-08-12T13:47:41.803 に答える