adding the implemention of cookies only
… try to write tests and run them, nothing shows
needs codeclimate to change the limit of Cognitive Complexity
Tokens Controller
`
def create
create_token_and_set_header(current_resource, resource_name)
get_token_and_set_cookie
access_token = get_access_token_from_headers
remove_access_token_from_headers
@refresh_token.destroy
blacklist_token if ApiGuard.blacklist_token_after_refreshing
render_success(data: access_token, message: I18n.t('api_guard.access_token.refreshed'))
end
private
def get_access_token_from_headers
response.headers['Access-Token'] if response.headers
end
def get_token_and_set_cookie
refresh_token = response.headers['Refresh-Token']
cookies.signed[:jti]={
:value=>refresh_token,
:httponly=>true
}
remove_keys = %w(Refresh-Token)
response.headers.delete_if { |key| remove_keys.include?(key)}
end
def remove_access_token_from_headers
remove_keys = %w(Access-Token Expire-At)
response.headers.delete_if { |key| remove_keys.include?(key)}
end
def find_refresh_token
refresh_token_from_header = cookies.signed[:jti]
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
`
Registration Controller
def create
init_resource(sign_up_params)
if resource.save
create_token_and_set_header(resource, resource_name)
get_token_and_set_cookie
access_token = get_access_token_from_headers
remove_access_token_from_headers
render_success(data: access_token,message: I18n.t('api_guard.registration.signed_up'))
else
render_error(422, object: resource)
end
end
def destroy
current_resource.destroy
render_success(message: I18n.t('api_guard.registration.account_deleted'))
end
private
def get_access_token_from_headers
response.headers['access-token']
end
def remove_access_token_from_headers
remove_keys = %w(Access-Token Expire-At)
response.headers.delete_if { |key| remove_keys.include?(key)}
end
def get_token_and_set_cookie
refresh_token = response.headers['Refresh-Token']
cookies.signed[:jti]={
:value=>refresh_token,
:httponly=>true
}
remove_keys = %w(Refresh-Token)
response.headers.delete_if { |key| remove_keys.include?(key)}
end
Tokens Controller
def create
create_token_and_set_header(current_resource, resource_name)
get_token_and_set_cookie
access_token = get_access_token_from_headers
remove_access_token_from_headers
@refresh_token.destroy
blacklist_token if ApiGuard.blacklist_token_after_refreshing
render_success(data: access_token, message: I18n.t('api_guard.access_token.refreshed'))
end
private
def get_access_token_from_headers
response.headers['Access-Token'] if response.headers
end
def get_token_and_set_cookie
refresh_token = response.headers['Refresh-Token']
cookies.signed[:jti]={
:value=>refresh_token,
:httponly=>true
}
remove_keys = %w(Refresh-Token)
response.headers.delete_if { |key| remove_keys.include?(key)}
end
def remove_access_token_from_headers
remove_keys = %w(Access-Token Expire-At)
response.headers.delete_if { |key| remove_keys.include?(key)}
end
def find_refresh_token
refresh_token_from_header = cookies.signed[:jti]
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
Thanks for the PR. I will take a look in a week.
cool, let me know. if I did something wrong,
Thanks for this. I am interested in seeing this feature merged.
Would it be possible, please, to add some notes about the configuration options to README.md and adding them to the initializer template in lib/generators/api_guard/initializer/templates/initializer.rb? I think they are straightforward but being able to find them without reading through the code would be helpful.
@jrmhaig hey, sorry for not being late in my response, I am applying to some jobs this day so I am busy looking, yeah for sure, I will be free this weekend, I am gonna write some docs about, thanks
@jrmhaig hey, sorry for not being late in my response, I am applying to some jobs this day so I am busy looking, yeah for sure, I will be free this weekend, I am gonna write some docs about, thanks
No problem. I was really just saying that this would be a great feature to have and thank you for working on it. Good luck in your job applications.
@jrmhaig thanks dude, love to hear that
let me give you a flow of production-ready authorization
- we create an access token and refresh token ( the purpose of refresh tokens is just for refreshing the access token ( so it's getting a new access token to maintain the session of the user and not having to ask the user to log in again)
- we pass the access token just in the response body, and refresh token in the cookies for preventing XSS attacks through any kind of vulnerabilities in our app that gonna lead that attack to us.
- the client (react) will accept the request, and set the cookies in the user cookies session ( refresh tokens can expire in 1 year or so, the access token is different, you need to make sure to expire the access token in 1h or 30 min ) and store that access token in a variable in react and persist that or just keep the access token in the session so you just gonna keep it in the server, not the client
and also I get what are you saying but we can refresh them both, the access token and the refresh token in the same query, an example is when we identify a 403 forbidden response we send to the backend the refresh token, we expire the access token and refresh token and get new ones
and also the purpose of blacklisting the access token is when a user's account gets hacked and that user still has the access token we can just expire that immediately but include that in the blacklist table and also it gives us the power to keep tracking of all the sessions that the user created ( smartphone, laptop, ...)