Skip to content

Latest commit

 

History

History
179 lines (136 loc) · 5.76 KB

v2_v4.md

File metadata and controls

179 lines (136 loc) · 5.76 KB

Migrating FingerprintJS v2 to v4

This guide shows how to migrate your code from FingerprintJS version 2 to version 4.

License

Please note that our licensing terms for v4 has changed. The table below indicates the different use-cases that shall require a commercial license to be purchased.

Before license change (versions 3.x and lower) After license change (versions 4.x and higher)
License MIT BSL 1.1
Use FingerprintJS for research, explorative and all other non-commercial purposes
Fork FingerprintJS repository for production ❌ (requires a commercial license to be purchased)
Use FingerprintJS in production ❌ (requires a commercial license to be purchased)

To purchase a license for uses not authorized by BSL, please contact us at [email protected].

Browser support

The support of Internet Explorer and some other browsers has been dropped. See the list of supported browsers in the browser support guide.

Installation

The migration process depends on the way you install the library.

CDN

Use the new URL: https://openfpcdn.io/fingerprintjs/v4/iife.min.js

Bower

Bower support is dropped, choose another installation method.

NPM or Yarn

Update the package version:

npm install @fingerprintjs/fingerprintjs
# or
yarn add @fingerprintjs/fingerprintjs

The new version sends HTTP requests to collect usage statistics, they can be disabled. See this page for more details.

Remove the type declaration package. You don't need it because the type declaration is embedded into the main package in v4:

npm remove @types/fingerprintjs__fingerprintjs
# or
yarn remove @types/fingerprintjs__fingerprintjs

Initialization

Version 4 doesn't require you to call requestIdleCallback or setTimeout manually. Instead, you must call FingerprintJS.load(). This function returns a promise that resolves with an agent object. The agent has a get method that you will use instead of calling Fingerprint2.get directly:

- requestIdleCallback(() => {
-   Fingerprint2.get(result => {
+ const fpPromise = FingerprintJS.load()
+ fpPromise
+   .then(fp => fp.get()){
+   .then(result => {
      // Handle the result
    })
- })

Handling the result

Version 4 emits a complete visitor identifier, you don't need to derive it from the components by yourself:

  fp.get().then(result => {
-   const values = result.map(function (component) { return component.value })
-   const visitorId = Fingerprint2.x64hash128(values.join(''), 31)
+   const visitorId = result.visitorId
  })

If you need to get the raw components, you can, but the format is different:

const result = await fp.get()
console.log(result)

- [
-   { key: 'ordinaryComponent', value: 'Some value' },
-   { key: 'componentWithError', value: 'error' },
-   { key: 'notAvailableComponent', value: 'not available' },
-   { key: 'excludedComponent', value: 'excluded' },
- ],
+ {
+   visitorId: 'aStringWithAnIdentifier',
+   components: {
+     ordinaryComponent: { value: 'some value', duration: 4 },
+     componentWithError: { error: { message: 'This is the error object' }, duration: 2 },
+     notAvailableComponent: { value: undefined, duration: 1 },
+     excludedComponent: { value: 'Exclusion is not supported', duration: 10 },
+   }
+ }

Customization

Version 4 has no options for customization, it provides a good built-in setup. Nevertheless, you can exclude built-in entropy components and add custom entropy components manually. See the extending guide to learn more.

How to update without losing the identifiers

The identifiers produced by version 4 don't match the identifiers produced by version 2. If this is an issue for you, you can implement the following strategy.

Install version 4 together with version 2:

<script src="https://cdn.jsdelivr.net/npm/@fingerprintjs/fingerprintjs@2/dist/fingerprint2.min.js"></script>
<script src="https://openfpcdn.io/fingerprintjs/v4/iife.min.js"></script>

(if you prefer NPM or Yarn, see this note)

When you need the visitor identifier, get identifiers from both versions:

Promise.all([
  new Promise(resolve => {
    requestIdleCallback(() => {
      Fingerprint2.get(resolve)
    })
  }),
  FingerprintJS.load().then(fp => fp.get())
]).then(([v2Result, v4Result]) => {
  // Handle both the results. For example, send to your server.
  const v2VisitorId = Fingerprint2.x64hash128(
    v2Result.map(component => component.value).join(''),
    31
  )
  const v4VisitorId = v4Result.visitorId
  return fetch(
    '/visitor'
      + `?fingerprintV2=${encodeURIComponent(v2VisitorId)}`
      + `&fingerprintV4=${encodeURIComponent(v4VisitorId)}`
  )
})

Make your server search using both the identifiers. Save the version 4 identifier:

-- Getting the visitor
SELECT * FROM visitors
WHERE
  fingerprintV2 = :fingerprintV2 OR
  fingerprintV4 = :fingerprintV4;

-- Update the visitor identifier
-- to switch to the fingerprint version 4
UPDATE visitors
SET fingerprintV4 = :fingerprintV4
WHERE fingerprintV2 = :fingerprintV2;

-- Saving a new visitor
INSERT INTO visitors (..., fingerprintV4)
VALUES (..., :fingerprintV4);

Later, when you get many enough identifiers of the version 4, remove the version 2 library and its identifiers.

The version 4 fingerprints may change after updating to a new major version, so you should extend this strategy to minor sub-versions of version 4 too.