Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding the implemention of cookies only #63

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,15 @@ GEM
factory_bot_rails (6.1.0)
factory_bot (~> 6.1.0)
railties (>= 5.0.0)
ffi (1.13.1)
ffi (1.15.5)
globalid (0.4.2)
activesupport (>= 4.2.0)
i18n (1.8.5)
concurrent-ruby (~> 1.0)
jaro_winkler (1.5.4)
json (2.3.1)
jwt (2.2.2)
listen (3.2.1)
listen (3.7.1)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
loofah (2.7.0)
Expand Down Expand Up @@ -139,7 +139,7 @@ GEM
thor (>= 0.20.3, < 2.0)
rainbow (3.0.0)
rake (13.0.1)
rb-fsevent (0.10.4)
rb-fsevent (0.11.2)
rb-inotify (0.10.1)
ffi (~> 1.0)
rspec-core (3.9.2)
Expand Down Expand Up @@ -205,4 +205,4 @@ DEPENDENCIES
sqlite3 (~> 1.4)

BUNDLED WITH
2.1.4
2.3.7
13 changes: 12 additions & 1 deletion app/controllers/api_guard/tokens_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,19 @@ def create
private

def find_refresh_token
refresh_token_from_header = request.headers['Refresh-Token']
unless ApiGuard.enable_cookies_response
refresh_token_from_header = request.headers['Refresh-Token']

if refresh_token_from_header
@refresh_token = find_refresh_token_of(current_resource, refresh_token_from_header)
return render_error(401, message: I18n.t('api_guard.refresh_token.invalid')) unless @refresh_token
else
render_error(401, message: I18n.t('api_guard.refresh_token.missing'))
end

end

refresh_token_from_header = request.cookies.signed[:kebbah]
if refresh_token_from_header
@refresh_token = find_refresh_token_of(current_resource, refresh_token_from_header)
return render_error(401, message: I18n.t('api_guard.refresh_token.invalid')) unless @refresh_token
Expand Down
12 changes: 12 additions & 0 deletions lib/api_guard.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@ module Test
autoload :ControllerHelper, 'api_guard/test/controller_helper'
end

mattr_accessor :enable_response_headers
self.enable_response_headers = true

mattr_accessor :add_domain_for_refresh_token
self.add_domain_for_refresh_token = nil

mattr_accessor :enable_response_body
self.enable_response_body = false

mattr_accessor :enable_cookies_response
self.enable_cookies_response = false

mattr_accessor :token_validity
self.token_validity = 1.day

Expand Down
7 changes: 6 additions & 1 deletion lib/api_guard/jwt_auth/authentication.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ def respond_to_missing?(method_name, include_private = false)
def authenticate_and_set_resources(resource_names)
@resource_names = resource_names

@token = request.headers['Authorization']&.split('Bearer ')&.last
if ApiGuard.enable_response_headers
@token = request.headers['Authorization']&.split('Bearer ')&.last
elsif ApiGuard.enable_cookies_response
@token = request.cookies.signed[:access_token][:access_token]
end

return render_error(401, message: I18n.t('api_guard.access_token.missing')) unless @token

authenticate_token
Expand Down
36 changes: 36 additions & 0 deletions lib/api_guard/jwt_auth/json_web_token.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def jwt_and_refresh_token(resource, resource_name, expired_token = false, expire
# Add custom data in the JWT token payload
payload.merge!(resource.jwt_token_payload) if resource.respond_to?(:jwt_token_payload)

# generate the access token and refresh token
[encode(payload), new_refresh_token(resource, expired_refresh_token)]
end

Expand All @@ -54,13 +55,48 @@ def create_token_and_set_header(resource, resource_name)
set_token_headers(access_token, refresh_token)
end

def create_token_and_set_in_strategy(resource, resource_name)
access_token, refresh_token = jwt_and_refresh_token(resource, resource_name)

if ApiGuard.enable_response_headers
set_token_headers(access_token, refresh_token)
elsif ApiGuard.enable_cookies_response
set_token_cookies(access_token, refresh_token)
end
end

# Set token details in response headers
def set_token_headers(token, refresh_token = nil)
response.headers['Access-Token'] = token
response.headers['Refresh-Token'] = refresh_token if refresh_token
response.headers['Expire-At'] = token_expire_at.to_s
end

def set_token_cookies(token, refresh_token)
# the secure way is just storing the refresh token in the cookies
# and leave the access token in the headers, but in your frontend,
# you need to make a accessor to the a variable called access token
# you can do this approche, or just store access token and refresh
# token in the headers
cookies.signed[:access_token] = {
value: { access_token: access_token, expires_at: token_expire_at.to_s},
http_only: true,
expires: ApiGuard.token_validity,
domain: ApiGuard.add_domain_for_refresh_token,
secure: true,
same_site: 'strict'
}

cookies.signed[:kebbah] = {
value: refresh_token,
http_only: true,
expires: ApiGuard.refresh_token_validity,
domain: ApiGuard.add_domain_for_refresh_token,
secure: true,
same_site: 'strict'
} if refresh_token
end

# Set token issued at to current timestamp
# to restrict access to old access(JWT) tokens
def invalidate_old_jwt_tokens(resource)
Expand Down
1 change: 1 addition & 0 deletions lib/api_guard/jwt_auth/refresh_jwt_token.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def destroy_all_refresh_tokens(resource)

refresh_tokens_for(resource).destroy_all
end

end
end
end
6 changes: 5 additions & 1 deletion lib/api_guard/response_formatters/renderer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ module ResponseFormatters
module Renderer
def render_success(data: nil, message: nil)
resp_data = { status: I18n.t('api_guard.response.success') }
resp_data[:message] = message if message
resp_data[:data] = data if data
resp_data[:message] = message if message

render json: resp_data, status: 200
end
Expand All @@ -20,3 +20,7 @@ def render_error(status, options = {})
end
end
end

class App
mattr_accessor :message
end
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ class TokensController < ApiGuard::TokensController
# private

# def find_refresh_token
# refresh_token_from_header = request.headers['Refresh-Token']
# if ApiGuard.enable_response_headers
# refresh_token_from_header = request.headers['Refresh-Token']
# elsif ApiGuard.enable_cookies_response
# refresh_token_from_header = request.cookies.signed[:kebbah]
# end
#
# if refresh_token_from_header
# @refresh_token = find_refresh_token_of(current_resource, refresh_token_from_header)
Expand Down