Get a free advice now!

    Pick the topic

    Developer OutsourcingWeb developingApp developingDigital MarketingeCommerce systemseEntertainment systems

    Thank you for your message. It has been sent.

    Tags

    Get User Fingerprint using UAParser.js

    Get User Fingerprint using UAParser.js

    How to identify a website visitor? How to do it even in incognito (private) mode? The old solution was to save the cookie in the browser, which would store the visitor’s unique user identifier. However, once saved, the cookie belongs to one domain and can’t be transferred between different browsers. A better solution is to use a function called fingerprint js for this.

    Every browser provides general information about the browser name, browser version, platform and user language. We can use it to create a user fingerprint, which will be used as UID (Unique Identifier). It stays the same, even if browser cache or settings are purged. Identification will also be working in the Incognito Mode of the browser. Fingerprint solutions are popular, especially in mobile app development.

    Black text on white background with a green button in the middle

    Fingerprint usage with UAParser.js

    Have you ever wondered how the same adverts are displayed when you’re navigating the Internet? Companies that are running ad networks use a similar technique: a user fingerprint is assigned to a user profile. Targeted ads are displayed basing on this data.

    User privacy

    It’s important to ask users for permission to use their data. Sensitive information, such as user IP address or user fingerprint, can be used to identify a single visitor. With the introduction of privacy laws, including GDPR (Europe) and CCPA (CA, USA), it’s crucial to get a user permission before requesting sensitive information.

    IpAddress should be enough?

    We can ask the following question: we already have userIP, so why should we use additional User-Agent data? One IP address can be assigned to multiple computers in the network. We need more information to target a single user. We can distinguish a single visitor using browser data.

    JS fingerprint demo

    As a demonstration, let’s say we have a database of visitor names. Every unique user fingerprint using js is assigned to his first name. Our goal will be to display a greeting: Hello [user_name]! To simplify the example, we’re going to hardcode data in javascript, but the recommended way of storing such data will be a database or an API.

    We’re going to use UAParser.js to get information about the Browser, Engine, OS, CPU, and Device type/model. It’s a javascript library, also available as an NPM package. Fingerprint value is hash generated from 5 values: the IP address and browser details.

    Hello John!

    Here is the entire application code written using React. On user visit, we’re asking for permission and then displaying greetings. The IP address is fetched using https://ip.nf/me.json. Execute the following command to install the required dependency:

    npm install ua-parser-js

    The main application:

    // App.jsx
    import React, { useState } from "react";
    import './App.css';
    import {Greetings} from "./Greetings";
    function App() {
      const [permissionGranted, setPermissionGranted] = useState(false);
      return (
        <div className="App">
            <div>
              <h3>Website wants to use your IP address and User-Agent details.<br />Click below to consent:</h3>
              <button className={'myButton'} onClick={() => {setPermissionGranted(true)}}>I'm granting permission {permissionGranted ? '✓' : ''}</button>
            </div>
            {permissionGranted ? <Greetings /> : ''}
        </div>
      );
    }
    export default App;
    

    The component for calculating the fingerprint and displaying greetings:

    // Greetings.jsx
    import React, {useState, useEffect} from 'react';
    import { UAParser } from 'ua-parser-js';
    export const Greetings = () => {
        const [ipAddress, setIpAddress] = useState(false);
        const [userFingerprint, setUserFingerPrint] = useState(false);
        const [firstName, setFirstName] = useState('Anonymous');
        const setIP = () => {
            fetch('https://ip.nf/me.json'
                , {
                    headers: {
                        'Content-Type': 'application/json',
                        'Accept': 'application/json'
                    }
                }
            )
                .then(function (response) {
                    return response.json();
                })
                .then(function (myJson) {
                    if(myJson.ip.ip){
                        setIpAddress(myJson.ip.ip);
                        // setIpAddress("127.0.0.1");
                    }
                });
        }
       const generateFingerprint = (ip, browserName, browserVersion, operatingSystem, language) =>{
            return generateHash(ip) + generateHash(browserName) + generateHash(browserVersion)
                + generateHash(operatingSystem) + generateHash(language);
        }
        const generateHash = (input) => {
            if(input){
                return input.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0);
            }
            return 0;
        }
        const setFingerprint = () => {
            const userAgentInfo = new UAParser();
            const browserName = userAgentInfo.getBrowser().name;
            const browserVersion = userAgentInfo.getBrowser().version;
            const platform = userAgentInfo.getOS().name;
            const userLang = (navigator.language) ? navigator.language : '';
            const temp1 = generateFingerprint(ipAddress, browserName, browserVersion, platform, userLang);
            if(temp1){
                setUserFingerPrint(temp1);
            }
        }
        const setNameFromDatabase = (fingerprint) => {
            // for demo purpose – data is hardcoded
            // for production application: use database storage or API
            // user fingerprint assigned to name
            const myDatabase = {
                3112300576: 'John',
                3112300577: 'Michael',
                3112300578: 'Anna'
            };
            if(myDatabase[fingerprint]) {
                setFirstName(myDatabase[fingerprint]);
            }
        }
        useEffect(() => {
            setIP();
        }, [])
        useEffect(() => {
            if(ipAddress){
                setFingerprint();
            }
            // eslint-disable-next-line
        }, [ipAddress])
        useEffect(() => {
            if(userFingerprint){
                setNameFromDatabase(userFingerprint);
            }
            // eslint-disable-next-line
        }, [userFingerprint])
        return (
            <>
                <h2>Hello {firstName}!</h2>
                { ipAddress && <p><strong>Your IP address: </strong> {ipAddress}</p> }
                <p><strong>Your Fingerprint: </strong> {userFingerprint}</p>
            </>
        );
    }
    

    The content of the CSS style:

    body {
      background-color: #fff;
      background-image:
              linear-gradient(90deg, transparent 79px, #abced4 79px, #abced4 81px, transparent 81px),
              linear-gradient(#eee .1em, transparent .1em);
      background-size: 100% 1.2em;
    }
    .App {
      text-align: center;
      max-width: 350px;
      margin: 50px auto;
    }
    .myButton {
      background-color:#44c767;
      border-radius:28px;
      border:1px solid #18ab29;
      display:inline-block;
      cursor:pointer;
      color:#ffffff;
      font-size:17px;
      padding:16px 31px;
      text-decoration:none;
      text-shadow:0px 1px 0px #2f6627;
    }
    .myButton:hover {
      background-color:#5cbf2a;
    }
    .myButton:active {
      position:relative;
      top:1px;
    }
    
    Black text and green button on white background

    More accurate targeting

    We can add additional parameters for calculating fingerprint js value to have more accurate results, e.g.: Geo Location, screen resolution, time of visit patterns, URL changes, a picture rendered with the HTML Canvas or WebGL, adBlock addon installed, a list of fonts in the system or some other advanced fingerprint signals. Instead of doing it manually, we can also use a ready-to-use NPM library: https://www.npmjs.com/package/@fingerprintjs/fingerprintjs.

    That’s it for today’s tutorial. Make sure to follow us for other useful tips and guidelines and don’t forget to sign up for our newsletter.

    Popular news

    eCommerce growth – is your business ready?
    • Services
    • Trends

    eCommerce growth – is your business ready?

    April 8, 2024 by createIT
    Digital marketing without third-party cookies – new rules
    • Technology
    • Trends

    Digital marketing without third-party cookies – new rules

    February 21, 2024 by createIT
    eCommerce healthcheck
    • Services
    • Trends

    eCommerce healthcheck

    January 24, 2024 by createIT
    Live Visitor Count in WooCommerce with SSE
    • Dev Tips and Tricks

    Live Visitor Count in WooCommerce with SSE

    December 12, 2023 by createIT
    Calculate shipping costs programmatically in WooCommerce
    • Dev Tips and Tricks

    Calculate shipping costs programmatically in WooCommerce

    December 11, 2023 by createIT
    Designing a cookie consent modal certified by TCF IAB
    • Dev Tips and Tricks

    Designing a cookie consent modal certified by TCF IAB

    December 7, 2023 by createIT
    Understanding the IAB’s Global Vendor List (GVL)
    • Dev Tips and Tricks

    Understanding the IAB’s Global Vendor List (GVL)

    December 6, 2023 by createIT

    Support – Tips and Tricks
    All tips in one place, and the database keeps growing. Stay up to date and optimize your work!

    Contact us