Program Tip

Rails API : 인증을 구현하는 가장 좋은 방법은 무엇입니까?

programtip 2020. 10. 17. 12:04
반응형

Rails API : 인증을 구현하는 가장 좋은 방법은 무엇입니까?


아직 개발되지 않은 모바일 앱용 API를 노출하는 Rails 4 앱을 작성 중입니다. 사용자는 모바일 앱에서 이메일과 비밀번호를 사용하여 인증합니다.

주제에 대해 꽤 많은 정보를 찾았습니다. 날짜가 지났거나 최적이 아닌 것을 식별하는 것은 어렵습니다. 너무 안전하지 않은 HTTP 기본 인증과 HTTP 토큰 기반 인증에 대해 읽었지만이를 일반 이메일 및 비밀번호 인증과 결합하는 방법을 잘 모르겠습니다 (Devise by 방법).

이를 구현하는 방법에 대한 현재 모범 사례가 무엇인지 알고 싶기 때문에 올바른 방향으로 진행할 것입니다.


보안 관점에서 중요한 점은 사용자의 이메일과 비밀번호를 토큰으로 한 번 교환 한 다음 해당 토큰을 후속 요청에 사용하는 것입니다. 이 때문입니다:

  1. 클라이언트 앱이 사용자의 암호를 유지하는 책임을지는 것을 원하지 않습니다. 버그 나 공격으로 인해 암호가 유출 될 수 있습니다.
  2. 서버에서 발급 한 토큰은 필요한 경우 토큰을 만료 할 수있는 기능을 제공합니다 (예 : 도난당한 장치를 잠 그거나 오작동하는 API 클라이언트를 차단).

다양한 수준의 복잡성으로이를 수행하는 방법에는 여러 가지가 있습니다.

다음은 토큰 기반 인증 (Devise를 사용하지 않지만 개념을 이해하는 데 여전히 관련이 있음)을 사용하여 Rails에서 API를 생성하기위한 매우 최근의 튜토리얼입니다. https://labs.kollegorna.se/blog/ 2015 / 04 / build-an-api-now /


또 다른 옵션은 아래 모듈을 devise MODEL에 포함시키고 auth_token을 테이블에 추가하는 것입니다.

app / models / concerns / token_authenticable.rb

module TokenAuthenticatable
  extend ActiveSupport::Concern

  included do
    before_save :ensure_auth_token
  end

  module ClassMethods
    def find_by_token(token)
      find_by(auth_token: token)
    end
  end

  def ensure_auth_token
    self.auth_token = generate_auth_token if auth_token.blank?
  end

  private

  def generate_auth_token
    loop do
      token = Devise.friendly_token
      break token unless self.class.exists?(auth_token: token)
    end
  end
end

app / controllers / api / v1 / login_controller.rb

...
 def login_user(params)
    if params[:authentication]
      @user = User.find_by(auth_token: params[:authentication])
      if @user.nil?
        render json: err('login user by token failed', ERR_USER_NOT_FOUND), status: :not_found
        event('login_user_by_auth_failed', 'token', params[:authentication])
        return
      else
        render status: :ok, json: @user
        return
      end
    else
      user = user.find_by(email: params[:email])
      if user.nil?
        event('login_user_failed_not_found', 'user_email', params[:email])
        render json: err("login user not found #{params[:email]}", ERR_USER_NOT_FOUND), status: :not_found
        return
      end
      if user.access_locked?
        event('login_user_blocked', 'user_id', user.id)
        render json: err("login user account is locked : #{user.id}", ERR_USER_LOCKED), status: :unauthorized
        return
      end
      unless user.try(:valid_password?, params[:password])
        event("login_user_password_does_not_match #{user.id}", 'user_id',  user.id)
        render json: err('login user password does not match', ERR_PASSWORD_NOT_MATCH), status: :unauthorized
        return
      end
      event('login_user_succeeded', 'user_id', user.id)
      @user= user
      if @user.save
        response.headers['authentication'] = @user.auth_token
        render status: :ok, json: @user
        return
      else
        render json: @user.errors, status: :unprocessable_entity
        return
      end
    end
  end
...

편집 : 수정 된 코드 브레이킹 오타


@ Roma149 이것은 개인적인 취향에 가깝지만 막 시작한 대부분의 사람들은 가장 쉬운 IMO이기 때문에 Devise를 사용합니다. OAuth2도 좋은 옵션입니다. 더 중요한 메모로 언제든지 The Ruby Toolbox 로 이동할 수 있습니다.

거기에는 보석에 대한 많은 좋은 정보가 있으며 보석의 나이와 인기도 알려줍니다. 이것은 또한 커뮤니티가 지금 정말로 괴롭히는 보석이나 오래된 보석을 구별 할 수있게 해줍니다.

Ruby와 Ruby On Rails에서는 항상 더 나은 gem이 아니라 프로젝트에 가장 적합한 것이 무엇인지 기억하세요!


Tiddle gem provides Devise strategy for token authentication in API-only Ruby on Rails applications. Its main feature is support for multiple tokens per user.

https://github.com/adamniedzielski/tiddle

참고URL : https://stackoverflow.com/questions/30038475/rails-api-best-way-to-implement-authentication

반응형