테마
Post-login Destination
/session/new 으로 들어온 사용자가 로그인에 성공한 뒤 어디로 가는지 결정하는 규칙. 일반 사용자/개발자/RP 흐름을 한 컨트롤러가 처리하므로 분기 의도를 모르면 "왜 갑자기 다른 호스트로 튕기지?" 라는 의문이 생긴다.
한 줄 요약
| 조건 | 도달 위치 |
|---|---|
return_to=/oauth/authorize?... (RP-initiated SSO) | same-host /oauth/authorize (RP 흐름 재개) |
return_to=/something-else (저장된 보호 페이지) | same-host 해당 path |
return_to 없음 (직접 방문 후 로그인) | cross-host handoff → https://start.1pass.dev/account |
왜 cross-host handoff 인가
/account 가 start.1pass.dev 에 host-locked (console_host_constraint). 한편 /session/new 는 api.1pass.dev 에만 존재. 호스트마다 session cookie 가 독립적이라 (cookie domain 을 .1pass.dev 로 넓힐 수 없음 — embed.1pass.dev iframe 격리), 같은 세션을 두 호스트에서 인증된 채로 보려면 일회용 핸드오프 토큰 (SessionHandoffToken) 으로 cookie 를 옮겨야 한다.
흐름 (production)
api.1pass.dev/session/new
│ (POST /session, no return_to)
▼
SessionsController#create
│
├─ SessionHandoffToken.issue!(target_host: "start.1pass.dev")
├─ cookies.delete(:session_id) # 단일 auth artifact
▼
302 → https://start.1pass.dev/session/handoff?token=...&return_to=%2Faccount
│
▼
SessionHandoffsController#show
│
├─ SessionHandoffToken.consume!(token, host: "start.1pass.dev")
├─ cookies.signed[:session_id] = session.id # start 호스트 cookie
▼
302 → /account (start.1pass.dev)흐름 (dev/test)
console_host_constraint 가 비프로덕션에서는 모든 호스트를 매치. cookie 호스트 분리도 없음 → handoff 토큰 없이 /account path 로 same-host redirect. 컨트롤러 가 자동 분기 (Rails.env.production?).
RP 흐름은 침범되지 않는다
/oauth/authorize 진입 시 Authentication concern 이 return_to 를 저장한 채 /session/new 로 리다이렉트 → 로그인 → return_to 가 있으므로 cross-host handoff 로 빠지지 않고 same-host /oauth/authorize 로 복귀.
ruby
# sessions_controller.rb#complete_login (HTML format)
if (target = post_login_redirect_path) # explicit / stored return_to
redirect_to target # same-host
else
redirect_to handoff_to_account_url(...) # cross-host /account
end회귀 방지 spec: spec/integrations/krx_listing_rp_integration_spec.rb
- "post-login fallback does NOT hijack RP flow (return_to is present)"
개발자도 일반 사용자다
User 는 단일 모델, role 필드로 developer? / admin? 판별. 개발자가 직접 /session/new 에 가서 로그인해도 /account 로 간다 (모두 보임). 거기 우상단 "개발자 콘솔 →" 링크가 /developer 진입점.
→ post-login 폴백을 /account 로 둔 게 양쪽 다 자연스러운 이유.
함정
post_login_redirect_path는nil을 반환할 수 있다. 이전엔|| developer_root_path폴백이 있었지만 일반 사용자가 권한 게이트에 차이는 문제로 제거. 폴백 분기는 caller (complete_login) 에서 명시적으로 handoff 호출.- cookie 삭제는 production 분기에서만 (
Rails.env.production?). 비프로덕션에서 삭제하면 same-host/account로 가서 인증 풀려 무한 루프. SessionHandoffToken#consume!가 host 일치 검증을 포함 — api 토큰을 start 에서 redeem 시도하면 거부.
관련 코드
app/controllers/sessions_controller.rb#complete_loginapp/controllers/sessions_controller.rb#handoff_to_account_urlapp/controllers/session_handoffs_controller.rbapp/models/session_handoff_token.rbapp/policies/handoff_policy.rbconfig/initializers/cross_host_handoff.rb
관련 spec
spec/requests/sessions_spec.rb#"HTML fallback when no return_to"spec/requests/session_handoffs_spec.rbspec/policies/handoff_policy_spec.rbspec/integrations/krx_listing_rp_integration_spec.rb