-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Add support for sending and receiving the auth token via a server cookie #1453
Changes from 4 commits
c5043c7
d20d24f
c623d51
3cdc09b
7592336
536340b
66f8fa9
a486ba8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,11 +35,20 @@ def set_user_by_token(mapping = nil) | |
access_token_name = DeviseTokenAuth.headers_names[:'access-token'] | ||
client_name = DeviseTokenAuth.headers_names[:'client'] | ||
|
||
# gets values from cookie if configured and present | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can all this new cookie code be in a new module like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can, my only push back would be that hopefully in the future we'll allow turning off headers (for the security reasons mentioned in point two of the description). In that case, it might feel a bit disjointed to have the header logic in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, see my recent realization. That may clean up the amount of noise in this file considerably. |
||
parsed_auth_cookie = {} | ||
if DeviseTokenAuth.cookie_enabled | ||
auth_cookie = request.cookies[DeviseTokenAuth.cookie_name] | ||
if auth_cookie.present? | ||
parsed_auth_cookie = JSON.parse(auth_cookie) | ||
end | ||
end | ||
|
||
# parse header for values necessary for authentication | ||
uid = request.headers[uid_name] || params[uid_name] | ||
uid = request.headers[uid_name] || params[uid_name] || parsed_auth_cookie[uid_name] | ||
@token = DeviseTokenAuth::TokenFactory.new unless @token | ||
@token.token ||= request.headers[access_token_name] || params[access_token_name] | ||
@token.client ||= request.headers[client_name] || params[client_name] | ||
@token.token ||= request.headers[access_token_name] || params[access_token_name] || parsed_auth_cookie[access_token_name] | ||
@token.client ||= request.headers[client_name] || params[client_name] || parsed_auth_cookie[client_name] | ||
|
||
# client isn't required, set to 'default' if absent | ||
@token.client ||= 'default' | ||
|
@@ -101,6 +110,11 @@ def update_auth_header | |
# update the response header | ||
response.headers.merge!(auth_header) | ||
|
||
# set a server cookie if configured | ||
if DeviseTokenAuth.cookie_enabled | ||
cookies[DeviseTokenAuth.cookie_name] = DeviseTokenAuth.cookie_attributes.merge(value: auth_header.to_json) | ||
end | ||
|
||
else | ||
unless @resource.reload.valid? | ||
@resource = @resource.class.find(@resource.to_param) # errors remain after reload | ||
|
@@ -123,8 +137,15 @@ def refresh_headers | |
# cleared by sign out in the meantime | ||
return if @used_auth_by_token && @resource.tokens[@token.client].nil? | ||
|
||
_auth_header_from_batch_request = auth_header_from_batch_request | ||
|
||
# update the response header | ||
response.headers.merge!(auth_header_from_batch_request) | ||
response.headers.merge!(_auth_header_from_batch_request) | ||
|
||
# set a server cookie if configured | ||
if DeviseTokenAuth.cookie_enabled | ||
cookies[DeviseTokenAuth.cookie_name] = DeviseTokenAuth.cookie_attributes.merge(value: _auth_header_from_batch_request.to_json) | ||
end | ||
end # end lock | ||
end | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -55,6 +55,16 @@ def destroy | |
user.tokens.delete(client) | ||
user.save! | ||
|
||
if DeviseTokenAuth.cookie_enabled | ||
if DeviseTokenAuth.cookie_attributes[:domain] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just realized that we might need to be smarter about determining the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make sense, remember to use allowlist instead of whitelist There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @apuntovanini Another option is to just support passing to the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here are the changes for that second option I mentioned. And our project's config looks like:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤦 I just saw this in the in the Rails docs:
So I can totally gut this Proc logic now, and instead just pass along either a string or Array from the config to the cookie call. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See this commit. So much cleaner! I wish I had realized that earlier, lol. |
||
# If a cookie is set with a domain specified then it must be deleted with that domain specified | ||
# See https://stackoverflow.com/a/6244724/1747491 | ||
cookies.delete(DeviseTokenAuth.cookie_name, domain: DeviseTokenAuth.cookie_attributes[:domain]) | ||
else | ||
cookies.delete(DeviseTokenAuth.cookie_name) | ||
end | ||
end | ||
|
||
yield user if block_given? | ||
|
||
render_destroy_success | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drive-by that popped up while debugging a test