Skip to content

Instantly share code, notes, and snippets.

@sirhopcount
Forked from theCrab/authentication.rb
Created October 21, 2016 05:08
Show Gist options
  • Save sirhopcount/d25c6281cf0349084a460c175b9be3d2 to your computer and use it in GitHub Desktop.
Save sirhopcount/d25c6281cf0349084a460c175b9be3d2 to your computer and use it in GitHub Desktop.
A Hanami Framework authentication based on JSON Web Tokens.
# lib/authentications/authentication.rb
# @api auth
# Authentication base class
#
module Authentication
def self.included(base)
base.class_eval do
before :authenticate!
expose :current_user
end
end
def authenticate!
halt 401 unless authenticated?
end
def current_user
@current_user ||= authenticate_user
end
private
def authenticated?
!!current_user
end
def authenticate_user
# Every api request has an access_token in the header
# Find the user and verify they exist
jwt = JWT.decode(payload, HANAMI_ENV['HMAC_SECRET'], algorithm: 'HS256')
#user = User.with_token(headers['Authentication'])
user = UserRepository.find(jwt.user_id)
if user && !user.revoked
return @current_user = user
end
end
end
# apps/web/controllers/sessions/create.rb
require 'jwt'
module Web
module Controllers
module Sessions
class Create
include Web::Action
accept :json
params do
param :username, type: String, presence: true
param :password, type: String, presence: true
end
def call(params)
halt 422 unless params.valid?
login
end
def login
user = UserRepository.find_by_username(params[:username])
halt 401 unless user
halt 403 unless valid_password?(user.password_hash)
options = { iss: 'http://hanamirb.org/', exp: 804700, user_id: user.id, audience: 'github' }
token = JWT.encode(options, HANAMI_ENV['HMAC_SECRET'], algorithm: 'HS256')
response.status = 200
response.body = { access_token: token, user: user, .... }.to_json
end
def authenticate!
# Nothing to see here, move along.
end
private
def valid_password?(password)
BCrypt::Password.new(params[:password]) == password
end
end
end
end
end

This is an attempt to get this project going. It's long overdue. This project is meant to be simple and plugable. Hanami is growing and at some point the one thing holding developers back is the User Authentication. So we need to cover this area so we move forward quick. This should be a community effort. A basic agnostic barebones gem that you can build on.

Mantra

JSON First.

This project requires gem 'jwt'

Features

  • login
  • recover_password
  • current_user
  • revoke_access
#lib/app_name/entities/user.rb
class User
include Hanami::Entity
attributes :username, :password_hash, :email, :access_token, :revoked, :pw_recovery_token, :created_at, :updated_at
def with_token(token)
token = token.sub('Bearer ', '').strip
UserRepository.find_by_access_token(token) # TODO: We actually do not need to persist this token in the db. Enc/Decode with JWT
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment