Skip to content

Instantly share code, notes, and snippets.

@StasKoval
Forked from theCrab/authentication.rb
Created April 11, 2016 11:17
Show Gist options
  • Save StasKoval/44932171f02887654a1666f5af427cff to your computer and use it in GitHub Desktop.
Save StasKoval/44932171f02887654a1666f5af427cff 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