Skip to content

Instantly share code, notes, and snippets.

@jianhandev
Created December 6, 2020 07:04
Show Gist options
  • Save jianhandev/09ef047b2b1490c15710e9377d502190 to your computer and use it in GitHub Desktop.
Save jianhandev/09ef047b2b1490c15710e9377d502190 to your computer and use it in GitHub Desktop.
# This class authenticates a valid user by generating a JWT token
class AuthenticateUser
def initialize(email, password)
@email, @password = email, password
end
def token
JsonWebToken.encode({ user_id: user.id })
end
attr_reader :email, :password
private
def user
user = User.find_by(email: email)
if user && user.authenticate(password)
return user
else
raise(ExceptionHandler::AuthenticationError,
Message.invalid_credentials)
end
end
end
class AuthenticationController < ApplicationController
skip_before_action :authorize_request
def login
token = AuthenticateUser
.new(auth_params[:email], auth_params[:password])
.token
render json: { user: user, token: token}
end
private
def user
User
.find_by(email: auth_params[:email])
.as_json(except: :password_digest)
end
def auth_params
params.require(:authentication).permit(:email, :password)
end
end
# This class is initialized with a http headers object,
# attempts to extract the authentication token
# and decodes the token to verify if it is valid
class AuthorizeApiRequest
def initialize(headers = {})
@headers = headers
end
def user
decoded_token = JsonWebToken.decode(token)
begin
User.find(decoded_token[:user_id])
rescue => err
raise(ActiveRecord::RecordNotFound,
err.message)
nil
end
end
private
attr_reader :headers
def token
if headers['Authorization'].present?
headers['Authorization'].split(' ').last
else
raise(ExceptionHandler::MissingToken,
Message.missing_token)
end
end
end
class JsonWebToken
class << self
HMAC_SECRET = Rails.application.credentials.secret_key_base
def encode(payload)
# token expires in 30 minutes
payload[:exp] = Time.now.to_i + 3600
JWT.encode(payload, HMAC_SECRET)
end
def decode(token)
begin
body = JWT.decode(token, HMAC_SECRET)[0]
HashWithIndifferentAccess.new(body)
rescue JWT::DecodeError
raise(ExceptionHandler::InvalidToken,
Message.invalid_token)
nil
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment