I am moving my Rails 5.2.4 app from Heroku to a Linode: Ubuntu 20.4, nginx reverse proxy, Unicorn server. It's all installed and running under SSL, EXCEPT: when a user logs in, the app produces NO cookies: not session ID (I have a DB-based session store; this is the record id), not a remember_user_token from Warden, not a CSRF token, nothing.
I have an after_action which reports response headers. Here is the output on the Heroku server:
Started POST "/users/sign_in" for 157.131.107.151 at 2020-07-25 23:44:20 +0000
Processing by SessionsController#create as JSON
Parameters: {"utf8"=>"✓", "user"=>{"login"=>"upstill", "password"=>"[FILTERED]", "remember_me"=>"1"}, "disableWith"=>"SIGN IN"}
FLASH messages extant for sessions#create (check_flash):
Full Request URL: https://www.recipepower.com/users/sign_in
Request header: HTTP_X_CSRF_TOKEN: ...
Request header: HTTP_X_REQUESTED_WITH: XMLHttpRequest
Request header: HTTP_REFERER: https://www.recipepower.com/home
Request header: HTTP_HOST: www.recipepower.com
Request header: HTTP_X_FORWARDED_PROTO: https
Request header: rack.url_scheme: https
Request header: HTTP_COOKIE: _rp_session=...
Request header: rack.request.cookie_hash: _rp_session: ...
Request header: warden:
Request COOKIE JAR: _rp_session: '...'
Request SESSION: session_id: '...'
Request SESSION: _csrf_token: '...'
User Load (2.6ms) SELECT "users".* FROM "users" WHERE (lower(username) = 'upstill' OR lower(email) = 'upstill') ORDER BY "users"."id" ASC LIMIT $1 [["LIMIT", 1]]
(1.3ms) BEGIN
User Update (3.8ms) UPDATE "users" SET "remember_created_at" = $1, "updated_at" = $2 WHERE "users"."id" = $3 [["remember_created_at", "2020-07-25 23:44:20.114245"], ["updated_at", "2020-07-25 23:44:20.116394"], ["id", 3]]
(91.9ms) COMMIT
(1.3ms) BEGIN
User Update (1.6ms) UPDATE "users" SET "updated_at" = $1, "sign_in_count" = $2, "current_sign_in_at" = $3, "last_sign_in_at" = $4 WHERE "users"."id" = $5 [["updated_at", "2020-07-25 23:44:20.216390"], ["sign_in_count", 919], ["current_sign_in_at", "2020-07-25 23:44:20.214547"], ["last_sign_in_at", "2020-07-25 22:21:03.602136"], ["id", 3]]
(2.2ms) COMMIT
GOTO_URL = https://www.recipepower.com/redirect/go?to=%22%2Fusers%2F3%2Fcollection%3Fresult_type%3Dcookmarks%22
Redirected to https://www.recipepower.com/redirect/go?to=%22%2Fusers%2F3%2Fcollection%3Fresult_type%3Dcookmarks%22
Response Header : Location: https://www.recipepower.com/redirect/go?to=%22%2Fusers%2F3%2Fcollection%3Fresult_type%3Dcookmarks%22
Response Header : Cache-Control: no-cache
Response Header : Content-Type: text/html; charset=utf-8
Response Header : Set-Cookie: rp_uuid=8aa6f1b27fbaa409ea88513ef6c5f95a; path=/
remember_user_token=...; domain=www.recipepower.com; path=/; expires=Sat, 08 Aug 2020 23:44:20 -0000; secure; HttpOnly
Response COOKIE: rp_uuid: 8aa6f1b27fbaa409ea88513ef6c5f95a
Response COOKIE: remember_user_token: ...
2020
Completed 302 Found in 193ms (ActiveRecord: 107.0ms)
And here is the corresponding report from the app on Ubuntu.
Started POST "/users/sign_in" for 157.131.107.151 at 2020-07-25 17:48:41 -0700
Processing by SessionsController#create as JSON
Parameters: {"utf8"=>"✓", "user"=>{"login"=>"upstill", "password"=>"[FILTERED]", "remember_me"=>"1"}, "disableWith"=>"SIGN IN"}
FLASH messages extant for sessions#create (check_flash):
Full Request URL: https://staging.recipepower.com/users/sign_in
Request header: HTTP_X_CSRF_TOKEN: ...
Request header: HTTP_X_REQUESTED_WITH: XMLHttpRequest
Request header: HTTP_REFERER: https://staging.recipepower.com/users/3/collection?result_type=cookmarks
Request header: HTTP_HOST: staging.recipepower.com
Request header: HTTP_X_FORWARDED_PROTO: https
Request header: rack.url_scheme: https
Request header: HTTP_COOKIE: ...nothing here!
Request header: warden:
^[[1m^[[36mUser Load (4.0ms)^[[0m ^[[1m^[[34mSELECT "users".* FROM "users" WHERE (lower(username) = 'upstill' OR lower(email) = 'upstill') ORDER BY "users"."id" ASC LIMIT $1^[[0m [["LIMIT", 1]]
^[[1m^[[35m (0.9ms)^[[0m ^[[1m^[[35mBEGIN^[[0m
^[[1m^[[36mUser Update (1.0ms)^[[0m ^[[1m^[[33mUPDATE "users" SET "updated_at" = $1, "sign_in_count" = $2, "current_sign_in_at" = $3, "last_sign_in_at" = $4 WHERE "users"."id" = $5^[[0m [["updated_at", "2020-07-26 00:48:41.696603"], ["sign_in_count", 923], ["current_sign_in_at", "2020-07-26 00:48:41.694921"], ["last_sign_in_at", "2020-07-26 00:42:51.660563"], ["id", 3]]
^[[1m^[[35m (1.0ms)^[[0m ^[[1m^[[35mCOMMIT^[[0m
GOTO_URL = https://staging.recipepower.com/redirect/go?to=%22%2Fusers%2F3%2Fcollection%3Fresult_type%3Dcookmarks%22
Redirected to https://staging.recipepower.com/redirect/go?to=%22%2Fusers%2F3%2Fcollection%3Fresult_type%3Dcookmarks%22
Response Header : X-Frame-Options: SAMEORIGIN
Response Header : X-XSS-Protection: 1; mode=block
Response Header : X-Content-Type-Options: nosniff
Response Header : X-Download-Options: noopen
Response Header : X-Permitted-Cross-Domain-Policies: none
Response Header : Referrer-Policy: strict-origin-when-cross-origin
Response Header : Location: https://staging.recipepower.com/redirect/go?to=%22%2Fusers%2F3%2Fcollection%3Fresult_type%3Dcookmarks%22
Response Header : Content-Type: text/html; charset=utf-8
Completed 302 Found in 169ms (ActiveRecord: 34.4ms)
As you can see, Warden is doing its thing, so at the very least there should be a remember_user_token being set. And this is from the Rails app, so the cookies are not being cleared by nginx or some middleware. I am completely baffled why it works in one environment and not the other.
NB: the Ubuntu app is running in a 'staging' environment on a subdomain, so that could be triggering some difference, but as far as I can tell, 'staging' is configured identically to, 'production'. The headers seem to indicate that everyone is fine with 'staging.recipepower.com'.
Thanks in advance for any suggestion! I'm really tearing my hair out here.