Skip to content

Support for configuring the browser fetch credentials mode in BrowserClient.#1937

Open
mauriceraguseinit wants to merge 3 commits into
dart-lang:masterfrom
mauriceraguseinit:master
Open

Support for configuring the browser fetch credentials mode in BrowserClient.#1937
mauriceraguseinit wants to merge 3 commits into
dart-lang:masterfrom
mauriceraguseinit:master

Conversation

@mauriceraguseinit

Copy link
Copy Markdown

This PR adds support for configuring the browser fetch credentials mode in BrowserClient.

Currently BrowserClient only exposes a boolean withCredentials option, which maps to either same-origin (when false) or include (when true). The browser fetch API, however, supports a third credentials mode, omit, which cannot be expressed through the existing boolean API. The only way to use omit today is to fork or copy BrowserClient and change the RequestInit manually.

Closes #1936.

What this changes

  • Adds a new BrowserCredentialsMode enum with the values omit, sameOrigin, and include, matching the three credentials modes defined by the [Fetch standard](https://fetch.spec.whatwg.org/#requestcredentials).
  • Adds a credentialsMode property and constructor parameter to BrowserClient, defaulting to BrowserCredentialsMode.sameOrigin to preserve the existing default behavior.
  • The RequestInit.credentials value is now derived from credentialsMode.

Backward compatibility

  • The existing withCredentials property is kept and continues to work, but is now deprecated because a boolean cannot represent all three credentials modes.
  • It is implemented as a compatibility adapter on top of credentialsMode:
    • the getter returns true only when credentialsMode is include;
    • the setter maps true to include and false to sameOrigin.
  • Existing code such as BrowserClient()..withCredentials = true keeps producing the same fetch behavior as before.

New usage

final client = BrowserClient(
  credentialsMode: BrowserCredentialsMode.omit,
);

  • I’ve reviewed the contributor guide and applied the relevant portions to this PR.

@google-cla

google-cla Bot commented Jun 2, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@brianquinlan brianquinlan self-requested a review June 22, 2026 23:44

@brianquinlan brianquinlan left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It it possible to construct tests for this? Also update CHANGELOG.md.

Comment thread pkgs/http/lib/src/browser_client.dart Outdated
///
/// Defaults to [BrowserCredentialsMode.sameOrigin], which matches the
/// previous behavior when [withCredentials] was `false`.
BrowserCredentialsMode credentialsMode;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make this private? I think that mutating it after construction is error-prone in any case.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that mutating this after construction is error-prone. However, withCredentials was a mutable public field in the original code. Making requestCredentials final and removing or disabling the withCredentials setter would break backwards compatibility for users who configure the client after instantiation.
How do we want to deal with this?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we make credentialsMode non-final but private. The withCredentials setter can mutate it. When withCredentials is removed, we can make credentialsMode final. WDYT?

Comment thread pkgs/http/lib/src/browser_client.dart Outdated
///
/// See also:
/// - https://fetch.spec.whatwg.org/#requestcredentials
enum BrowserCredentialsMode {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to call this RequestCredentials to match the spec?

Comment thread pkgs/http/lib/src/browser_client.dart Outdated
/// This corresponds to the browser `fetch` credentials mode `omit`.
omit('omit'),

/// Send credentials for same-origin requests only.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and only include credentials in same-origin replies.

Comment thread pkgs/http/lib/src/browser_client.dart Outdated
/// This corresponds to the browser `fetch` credentials mode `same-origin`.
sameOrigin('same-origin'),

/// Always send credentials, even for cross-origin requests.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...and include them in all responses.

…ch credentials modes

- Introduce `RequestCredentials` enum (`omit`, `same-origin`, `include`).
- Deprecate `withCredentials` getter and setter while maintaining full backwards compatibility.
- Update README.md with instructions on how to use the new parameter.
- Add unit tests verifying correct constructor initialization and fallback behaviors.
@mauriceraguseinit

Copy link
Copy Markdown
Author

I have taken the comments regarding the implementation into account and adjusted the code.

@github-actions

Copy link
Copy Markdown

PR Health

Unused Dependencies ⚠️
Package Status
http
❗ Show Issues
These packages may be unused, or you may be using assets from these packages:
* dart_flutter_team_lints
* shelf

For details on how to fix these, see dependency_validator.

This check can be disabled by tagging the PR with skip-unused-dependencies-check.

Breaking changes ✔️
Package Change Current Version New Version Needed Version Looking good?
http Non-Breaking 1.6.0 1.6.2-wip 1.6.2-wip ✔️

This check can be disabled by tagging the PR with skip-breaking-check.

API leaks ⚠️

The following packages contain symbols visible in the public API, but not exported by the library. Export these symbols or remove them from your publicly visible API.

Package Leaked API symbol Leaking sources
http RequestCredentials browser_client.dart::BrowserClient::requestCredentials
browser_client.dart::RequestCredentials::omit
browser_client.dart::RequestCredentials::sameOrigin
browser_client.dart::RequestCredentials::include
browser_client.dart::RequestCredentials::values
browser_client.dart::BrowserClient::new::requestCredentials

This check can be disabled by tagging the PR with skip-leaking-check.

Changelog Entry ✔️
Package Changed Files

Changes to files need to be accounted for in their respective changelogs.

This check can be disabled by tagging the PR with skip-changelog-check.

Coverage ⚠️
File Coverage
pkgs/http/lib/src/browser_client.dart 💔 Not covered

This check for test coverage is informational (issues shown here will not fail the PR).

This check can be disabled by tagging the PR with skip-coverage-check.

License Headers ✔️
// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
Files
no missing headers

All source files should start with a license header.

Unrelated files missing license headers
Files
pkgs/cupertino_http/example/example.dart
pkgs/http/example/main.dart
pkgs/http_multi_server/test/cert.dart

This check can be disabled by tagging the PR with skip-license-check.

Comment thread pkgs/http/CHANGELOG.md
@@ -1,3 +1,7 @@
## 1.6.2-wip

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1.6.1-wip (the -wip means Work-In-Progress) has not yet been released so you don't need to add a new version - just add your note to the 1.6.1-wip section.

Comment thread pkgs/http/CHANGELOG.md
@@ -1,3 +1,7 @@
## 1.6.2-wip

* Add `BrowserCredentialsMode` and `BrowserClient.credentialsMode` to support the `omit` browser fetch credentials mode. Deprecate `withCredentials`.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

80 columns please

Comment thread pkgs/http/pubspec.yaml
@@ -1,5 +1,5 @@
name: http
version: 1.6.1-wip
version: 1.6.2-wip

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can revert this.

@@ -0,0 +1,47 @@
// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was imagining that these tests could actually verify the client/server interaction by running an HTTP server. But now I'm not sure if that is possible without actually server the Dart-compiled Javascript from the same host/port as the test server. If it is not possible, then I don't think that these tests are valuable and you can delete them. Sorry for asking you to do this unnecessary work.

Comment thread pkgs/http/README.md
| [`package:fetch_client`][fetch] — [`FetchClient`][fetchclient] | Web | Dart, Flutter | ✅︎ | ✅︎ | ✅︎ |

> [!NOTE]
> [`BrowserClient`][browserclient] allows you to configure the browser `fetch` credentials mode (e.g., `omit`, `same-origin`, `include`) by passing the `requestCredentials` parameter to its constructor.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

80 columns

But this actually feels out of place to mention a client's feature here. Maybe add this to the dartdoc for BrowserClient?

class BrowserClient extends BaseClient {
/// Create a [BrowserClient].
///
/// By default, credentials are sent for same-origin requests only, which

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove. Most people will not be aware of the past behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expose the browser fetch credentials mode in BrowserClient

2 participants