Skip to content

Instantly share code, notes, and snippets.

@mike1011
Forked from esteedqueen/authenticable.rb
Created August 2, 2022 22:06
Show Gist options
  • Save mike1011/ba218a9c18091e9afc07577c89311cce to your computer and use it in GitHub Desktop.
Save mike1011/ba218a9c18091e9afc07577c89311cce to your computer and use it in GitHub Desktop.
JSON API User Registration and Sessions with Devise
module Authenticable
# Devise methods overwrite
def current_user
@current_user ||= User.find_by(authentication_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
class Api::V1::BaseController < ApplicationController
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
respond_to :json
skip_before_filter :verify_authenticity_token, :if => Proc.new { |c| c.request.format == 'application/json' }
protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format == 'application/json' }
skip_before_filter :authenticate_user!
include Authenticable
...
# set and include other common functions in here
end
class Api::V1::Users::RegistrationsController < Api::V1::BaseController
before_action :authenticate_with_token!, only: [:update, :destroy]
respond_to :json
def create
if params[:user][:email].nil?
render :status => 400,
:json => {:message => 'User request must contain the user email.'}
return
elsif params[:user][:password].nil?
render :status => 400,
:json => {:message => 'User request must contain the user password.'}
return
end
if params[:user][:email]
duplicate_user = User.find_by_email(params[:user][:email])
unless duplicate_user.nil?
render :status => 409,
:json => {:message => 'Duplicate email. A user already exists with that email address.'}
return
end
end
@user = User.create(sign_up_params)
if @user.save
render(status: 200, json: Api::V1::UserSerializer.new(@user, root:false).to_json)
else
render :status => 400,
:json => {:message => @user.errors.full_messages}
end
end
private
def sign_up_params
params.require(:user).permit(:email, :username, :password)
end
end
class Api::V1::SessionsController < Api::V1::BaseController
before_filter :authenticate_with_token!, except: [:create]
before_filter :ensure_params_exist
respond_to :json
def create
resource = User.find_for_database_authentication(
email: params[:user][:email]
)
return invalid_login_attempt unless resource
if resource.valid_password?(params[:user][:password])
sign_in(:user, resource)
render(status: 200, success: true, json: Api::V1::UserSerializer.new(resource, root:false).to_json)
return
end
invalid_login_attempt
end
def destroy
resource = current_user
resource.authentication_token = nil
resource.save
head 204
end
protected
def ensure_params_exist
return unless params[:user].blank?
render json: {
success: false,
message: "missing user parameter"
}, status: 422
end
def invalid_login_attempt
warden.custom_failure!
render json: {
success: false,
message: "Error with your email or password"
}, status: 401
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment