Problem/Motivation

When ip_login's auto-login feature is enabled, the EarlyIpLoginMiddleware runs on every request. For anonymous users, it:

  1. Starts a PHP session ($session->start()) to check if the user is authenticated
  2. Sets an ipLoginAttempted cookie on the response when no IP match is found

Both of these add Set-Cookie headers to the response, which prevents reverse proxies (Fastly, Varnish, Akamai, etc.) from caching the response. This is particularly impactful for decoupled/headless Drupal sites where the frontend makes frequent JSON:API requests to the backend — every JSON:API response becomes uncacheable.

For traditional Drupal sites this impact is limited to the first anonymous request per browser session (thanks to the ipLoginAttempted cookie), but for decoupled sites the impact is significant because API endpoints are hit on every page load.

Note for decoupled/headless sites: In a decoupled architecture, IP-based auto-login will not work for frontend visitors because the backend sees the frontend server's IP, not the end user's IP. The excluded_paths feature is primarily useful in this scenario to prevent the middleware from degrading cache performance on API endpoints that will never trigger an IP login anyway. If IP auto-login is needed for decoupled frontend users, a different approach such as client-side redirect-based login or CDN-level IP detection (e.g. Fastly VCL) would be required.

Steps to reproduce

  1. Install and enable ip_login with auto-login enabled (default configuration)
  2. Make an anonymous request to /jsonapi/node/article (or any JSON:API endpoint)
  3. Observe the response headers — Set-Cookie: ipLoginAttempted=1 is present
  4. This Set-Cookie header prevents Fastly/Varnish from caching the response

Proposed resolution

Add an "Excluded paths" configuration setting that allows site builders to specify paths that should be completely excluded from IP login processing. When a request matches an excluded path, the middleware bails out immediately - before session initialization, before cookie handling, and before the IP database lookup.

This means:

  • Excluded path responses have no Set-Cookie headers → fully cacheable by reverse proxies
  • Original behavior is preserved for all non-excluded paths
  • Empty by default → fully backward compatible

The implementation reuses the existing matchPath() method in EarlyIpLoginMiddleware for path matching, supporting wildcards (e.g. /jsonapi/*).

Remaining tasks

  • Review the MR

User interface changes

A new "Excluded paths" textarea is added to the IP Login settings form at /admin/config/people/ip_login, within the existing "Path specific IP logins" fieldset.

API changes

None.

Data model changes

A new excluded_paths string configuration value is added to ip_login.settings. An update hook (ip_login_update_9005) sets the default to an empty string for existing installations.

Issue fork ip_login-3585095

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

realityloop created an issue. See original summary.

realityloop’s picture

Issue summary: View changes

realityloop’s picture

Status: Active » Needs review

amateescu’s picture

Status: Needs review » Fixed

Looks great! Merged into 4.x, thanks :)

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.