Skip to content

Commit

Permalink
Merge pull request #7 from Blaze34/cookies
Browse files Browse the repository at this point in the history
work with cookies
  • Loading branch information
Rodion committed Jan 6, 2016
2 parents 202f6d5 + 0713c72 commit e02d39a
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ def show
self.resource = resource_class.confirm_by_token(params[:confirmation_token])
yield resource if block_given?
if resource.errors.empty?
render json: { auth_token: resource.jwt_token }
token, expires = resource.jwt_token_and_expires
send(:"set_jwt_cookie_for_#{resource_name}", token, expires)
render json: { auth_token: token }
else
render_errors resource.errors
end
Expand Down
4 changes: 3 additions & 1 deletion app/controllers/jwt_authentication/passwords_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ def update
if resource.errors.empty?
resource.unlock_access! if unlockable?(resource)
sign_in(resource_name, resource)
render json: { auth_token: resource.jwt_token }
token, expires = resource.jwt_token_and_expires
send(:"set_jwt_cookie_for_#{resource_name}", token, expires)
render json: { auth_token: token }
else
render_errors resource.errors
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ def create
if resource_saved
if resource.active_for_authentication?
sign_in(resource_name, resource, store: false)
token, expires = resource.jwt_token_and_expires
send(:"set_jwt_cookie_for_#{resource_name}", token, expires)
render json: {
auth_token: resource.jwt_token,
auth_token: token,
resource_name => resource
}
return
Expand Down
5 changes: 4 additions & 1 deletion app/controllers/jwt_authentication/sessions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ def create
self.resource = warden.authenticate!({ scope: resource_name, recall: "#{controller_path}#new", store: false })
sign_in(resource_name, resource)
yield resource if block_given?
render json: { auth_token: resource.jwt_token(sign_in_params[:remember_me]) }

token, expires = resource.jwt_token_and_expires(sign_in_params[:remember_me])
send(:"set_jwt_cookie_for_#{resource_name}", token, expires)
render json: { auth_token: token }
end

def destroy
Expand Down
2 changes: 2 additions & 0 deletions lib/generators/templates/jwt_authentication.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
# # Note: specified model should have `authentication_token` attribute (Model should "act as jwt authenticatable")
# # header_name - name of header to search auth_token in request
# # param_name - name of parameters to search auth_token in request
# # cookie_name - name of cookie to search auth_token in request
# # sign_in - method to be executed if authentication success, possible values: :devise, :simplified
# # if :devise selected, devises method sign_in() will be called at success authentication,
# # if :simplified selected, instance variable with name of resource will be set (@user or @terminal)
# config.models = {user: {header_name: 'X-User-Token',
# param_name: 'user_token',
# # cookie_name: 'user_token',
# sign_in: :devise}}
#
# # Configure mark of jwt timeout verification
Expand Down
4 changes: 1 addition & 3 deletions lib/jwt_authentication.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
require 'jwt_authentication/acts_as_jwt_authenticatable'
require 'jwt_authentication/acts_as_jwt_authentication_handler'
require 'jwt_authentication/configuration'
require 'jwt_authentication/engine'
require 'jwt'

module JwtAuthentication
extend Configuration

class Engine < ::Rails::Engine
end

NoAdapterAvailableError = Class.new(LoadError)

private
Expand Down
21 changes: 15 additions & 6 deletions lib/jwt_authentication/acts_as_jwt_authenticatable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module ActsAsJwtAuthenticatable
private :generate_authentication_token
private :token_suitable?
private :token_generator
private :token_expires_and_data
end

def ensure_authentication_token
Expand Down Expand Up @@ -36,13 +37,21 @@ def token_generator
@token_generator ||= TokenGenerator.new
end

def jwt_token(remember = false)
def token_expires_and_data(remember = false)
data = self.class.jwt_key_fields.inject({}) { |hash, field| hash[field] = self.send field; hash }
payload = {
exp: (Time.now + jwt_session_duration(remember)).to_i,
self.class.name.underscore => data
}
JWT.encode(payload, self.authentication_token)

[Time.now + jwt_session_duration(remember), data]
end

def jwt_token_and_expires(remember = false)
expires, data = token_expires_and_data(remember)
payload = {exp: expires.to_i, self.class.name.underscore => data}

[JWT.encode(payload, self.authentication_token), expires]
end

def jwt_token(remember = false)
jwt_token_and_expires(remember).first
end

def jwt_session_duration(remember = false)
Expand Down
15 changes: 15 additions & 0 deletions lib/jwt_authentication/engine.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module JwtAuthentication
class Engine < ::Rails::Engine
initializer 'jwt-autentication' do |app|
cookies_required = JwtAuthentication.models.any? { |key, value| value.is_a?(Hash) && value.has_key?(:cookie_name) }

if cookies_required
app.middleware.use ::ActionDispatch::Cookies

JwtAuthentication::JwtAuthenticationHandler.module_exec do
include ::ActionController::Cookies
end
end
end
end
end
20 changes: 16 additions & 4 deletions lib/jwt_authentication/entity.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,26 @@ def token_param_name(controller)
controller.jwt_models[name_underscore.to_sym][:param_name] || "#{name_underscore}_token"
end

def get_token_from_params_or_headers(controller)
(controller.request.headers[token_header_name(controller)] || controller.params[token_param_name(controller)]).to_s
def token_cookie_name(controller)
controller.jwt_models[name_underscore.to_sym][:cookie_name]
end

def cookie_enabled?(controller)
token_cookie_name(controller).present?
end

def get_token_from_cookie(controller)
cookie_enabled?(controller) ? controller.send(:cookies).signed[token_cookie_name(controller)] : nil
end

def get_token(controller)
(get_token_from_cookie(controller) || controller.request.headers[token_header_name(controller)] || controller.params[token_param_name(controller)]).to_s
end

def get_entity(controller)
begin
token = get_token_from_params_or_headers controller
payload = JWT.decode(token, nil, false)[0] # get payload; decode can riase: JWT::DecodeError
token = get_token controller
payload = JWT.decode(token, nil, false)[0] # get payload; decode can raise: JWT::DecodeError
keys = model.jwt_key_fields.inject({}) do |hash, field|
hash[field] = payload[name_underscore][field.to_s]
hash
Expand Down
19 changes: 19 additions & 0 deletions lib/jwt_authentication/jwt_authentication_handler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ module JwtAuthenticationHandler
private :authenticate_entity_by_jwt!
private :sign_in_handler
private :raise_error!
private :set_jwt_to_cookie

end

def authenticate_entity_by_jwt!(entity)
Expand All @@ -33,6 +35,17 @@ def raise_error!
raise JwtAuthentication::NotAuthenticated.new('Not authenticated')
end

def set_jwt_to_cookie(entity, token, expires)
return unless entity.cookie_enabled? self

cookie_name = entity.token_cookie_name(self)
if JwtAuthentication.jwt_timeout_verify
cookies.signed[cookie_name] = {value: token, expires: expires}
else
cookies.permanent.signed[cookie_name] = token
end
end

def valid_entity_name?(entity)
jwt_models.has_key? entity.name_underscore.to_sym
end
Expand Down Expand Up @@ -96,6 +109,12 @@ def define_jwt_authentication_helpers_for(entity)
raise_error! unless authenticate_entity_by_jwt!(_entity)
end.call(entity)
end

define_method "set_jwt_cookie_for_#{entity.name_underscore}".to_sym do |token, expires|
lambda do |_entity|
set_jwt_to_cookie(_entity, token, expires)
end.call(entity)
end
end
end
end
Expand Down

0 comments on commit e02d39a

Please sign in to comment.