lynndylanhurley / devise_token_auth

Token based authentication for Rails JSON APIs. Designed to work with jToker and ng-token-auth.
Do What The F*ck You Want To Public License
3.54k stars 1.13k forks source link

Weak ETag on Rack::ETag breaks change_headers_on_each_request #1024

Open Hugo-Hache opened 6 years ago

Hugo-Hache commented 6 years ago

While debugging an intermittent unlog issue on a mobile app consuming a Rails app powered by devise_token_oauth, we found occurrences of 304 returned to the client whereas the token was changed.

After investigating Rack::ETag (included by default in Rails middleware) we found that the etags generated are weak. They are indeed computed exclusively from the body of the response, and not the headers.

The front app receives a 304 without the new headers, and then get disconnected on the next request. I found a related issue #702, but for me the problem is not tied specifically to Batch mode, rather to any response body with a matching ETag ?

Rails log

I, [2017-11-17T14:58:41.558919 #10562]  INFO -- : [8ffd1e50-30f1-4797-8a18-db68445307ee] Processing by UsersController#me as JSON
I, [2017-11-17T14:58:41.559604 #10562]  INFO -- : [8ffd1e50-30f1-4797-8a18-db68445307ee] [HEADERS] Request: [["HTTP_USER_AGENT", "okhttp/3.3.1"], ["HTTP_ACCEPT_ENC
ODING", "gzip"], ["HTTP_ACCESS_TOKEN", "yVqRFmc6Ck215dwUYhbKcw"], ["HTTP_TOKEN_TYPE", "Bearer"], ["HTTP_EXPIRY", "1512136701"], ["HTTP_ACCEPT", "application/json"]
, ["HTTP_UID", "...@gmail.com"], ["HTTP_HOST", "..."], ["HTTP_CLIENT", "yj57ruo8PyYRejhPCOg06A"], ["HTTP_IF_NONE_MATCH", "W/\"e7ea902515fd1367d60
ea1d43be0bd11\""], ["HTTP_VERSION", "HTTP/1.1"]]

I, [2017-11-17T14:58:41.668189 #10562]  INFO -- : [8ffd1e50-30f1-4797-8a18-db68445307ee] [HEADERS] Response: {"X-Frame-Options"=>"SAMEORIGIN", "X-XSS-Protection"=>"1; mode=block", "X-Content-Type-Options"=>"nosniff", "Content-Type"=>"application/json; charset=utf-8", "access-token"=>"2BNB0XbMrZqJlR_JXBXtEg", "token-type"=>"Bearer", "client"=>"yj57ruo8PyYRejhPCOg06A", "expiry"=>"1512136721", "uid"=>"...@gmail.com"}
I, [2017-11-17T14:58:41.668407 #10562]  INFO -- : [8ffd1e50-30f1-4797-8a18-db68445307ee] Completed 200 OK in 109ms (Views: 3.8ms | ActiveRecord: 5.0ms)

Charles log

  | HTTP/1.1 304 Not Modified
-- | --
Date | Fri, 17 Nov 2017 13:58:41 GMT
Server | Apache/2.4.10 (Debian)
Keep-Alive | timeout=5, max=100
ETag | W/"e7ea902515fd1367d60ea1d43be0bd11"
Cache-Control | max-age=0, private, must-revalidate
Connection | Keep-alive
MaicolBen commented 6 years ago

Did you try with a more recent version? that version is from July 2016

krzysiek1507 commented 5 years ago

0.2.0 has the same problem

MaicolBen commented 5 years ago

no, that version is for solving a specific problem and is old, badge fury doesn't recognize release candidates, the most recent is 1.0.0rc2. But I don't think this is solved anyway, I'm thinking to disable change_headers_on_each_request in 1.1.0

shanehofstetter commented 5 years ago

I'm currently experiencing the same issue with a rails 5.2 app and devise_token_auth version 1.0.0. When I receive a 304 response the auth headers are completely missing and therefore i get an error at the next request. I also tried to disable change_headers_on_each_request which did not help. Currently I solved the problem by disabling ETag middleware completely.

torce commented 5 years ago

I'm currently experiencing the same issue with a rails 5.2 app and devise_token_auth version 1.0.0. When I receive a 304 response the auth headers are completely missing and therefore i get an error at the next request. I also tried to disable change_headers_on_each_request which did not help. Currently I solved the problem by disabling ETag middleware completely.

Same problem here with rails 5.2 and devise_token_auth 1.1.0. It was working perfectly in development, but when we deployed in staging/production this problem appeared.

The workaround worked perfectly (thanks!), but I wish that if this is not possible to fix, at least to be documented.