Rails authentication of users from a native Android application

I am trying to develop a Rails application that will mainly communicate with users of Android applications. People should be able to register and log in to the application (they can only fulfill most of the requests when they log in).

I looked through a lot of tutorials on how to make the equivalent of "session storage" in an application, but they all recommend using gem 'devise'it :token_authenticable, which has been deprecated for some time.

I need some serious advice on how to accomplish something equivalent. In my opinion, the client sends a request with parameters, such as {email: "some@email.com", password: "pw12345"}, I check that they correspond to the existing user and extract the token that this client will now send in each request through headers (for example, {"my_app_user_email": "some@email.com", "my_app_user_token":"abcdef123456"}).

I have already installed some methods with fake values, for example

def login
  if valid_user?(params[:email], params[:password])
    render json: {user_token: default_user_token}
  else
    render json: {message: 'Couldn\'t login'}, status: 401
  end
end

Where default_user_tokenis a fixed string, and is valid_user?also compared with fixed values.

I believe my problem is that this is the right approach, and if so, how can I create a model Userthat creates and validates tokens?

Extra bit of code

def verify_token # This already works by using default values in the Android app code
  email = request.headers['HTTP_MY_APP_USER_EMAIL']
  token = request.headers['HTTP_MY_APP_USER_TOKEN']
  user = User.find_by_email(email)
  user && user.valid_token?(token) # returns true for default_user_token, for now
end
+4
1

, . auth_token , . :

def generate_authentication_token!
    begin
        self.auth_token = Devise.friendly_token
    end while self.class.exists?(auth_token: auth_token)
end

, :

module Authenticable

  #Devise overwritten method
  def current_user
    @current_user ||= User.find_by(auth_token: request.headers['Authorization'])
  end

  def authenticate_with_token!
    render json: { errors: "Not authenticated" }, status: :unauthorized unless user_signed_in?
  end

  def user_signed_in?
    current_user.present?
  end

end

SessionController, / devise:

def create
    user_password = params[:session][:password]
    user_email = params[:session][:email]
    user = user_email.present? && User.find_by(email: user_email)

    if user
      if user.valid_password? user_password
        sign_in user, store: false
        user.generate_authentication_token!
        user.save
        render json: user, root: :user, status: 200, location: [:api, user]
      else
        render json: { errors: "Invalid email or password" }, status: 422
      end
    else
      render json: { errors: "Invalid email or password" }, status: 422
    end
  end

def destroy
    user = User.find_by(auth_token: params[:id])
    user.generate_authentication_token!
    user.save
    head 204
end

github, : https://github.com/brunojppb/api_on_rails

+1

Source: https://habr.com/ru/post/1609366/


All Articles