This is a feature request to support identification by device rather than just user agent in order to have greater confidence in individuality and distinction.

The JS library https://github.com/Valve/fingerprintjs2 looks promising.

It could work like so (assuming enabled and fingerprintjs2 lib is installed:

  1. On user login form submit
  2. fingerprintjs2 is invoked to get device fingerprint and stores in hidden form field
  3. Login History form alter reads submitted device fingerprint and uses instead of user agent

Other JS libs can be considered as well https://www.quora.com/Is-there-any-open-source-project-for-device-finger...

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

coltrane created an issue. See original summary.

coltrane’s picture

Here's a first pass patch that doesn't work yet but illustrates how I think it could

greggles’s picture

Title: Device ID provided by fingerprintjs2 » Add device ID provided by modules (browscap, fingerprintjs2)

Ben and I talked about this a bit and are thinking that it could make sense to make login_history a bit more extensible. Here's what I plan to work on.

Currently, login history records time, IP address, the nature of the login (one time or regular) and the full user agent. My interest in the module is that it helps both users and admins of a site determine if a login is legitimate. Additional code might send an email to a user if they log in from a new device or if a login happens 5 minutes after the last one but is from an IP address on the opposite side of the globe.

For those purposes it is useful to know if a browser user agent has changed, but it's also useful to know more generally chrome and not necessarily "Chrome/53.0.2785.143 Safari/537.36".

So...this module could:

  • invoke a hook on login to get data, e.g. letting other modules do detection (e.g. one that adds fingerprintjs2, one like browscap that detects browsers more generally)
  • store a hash of that data in the login_history table along with a login_id primary key that is an incrementing integer serial
  • set a cookie value in the browser with that hash
  • invoke another hook with the hash, the login_hostiry.login_id primary key, all that data, so that:
    1. a module could detect if this current login is likely from the same device or a new one
    2. the modules can store their data with the login_id

I think it makes sense for fingerprintjs2 to be a submodule (e.g. login_history_fingerprintjs2).

Eh?

greggles’s picture

Title: Add device ID provided by modules (browscap, fingerprintjs2) » Add device detection/ID provided by modules: browscap, fingerprintjs2

I was thinking more about the cookie that is sent to the client. The default hash from the module is just user agent and ip address, so any site visitor can calculate a value and send it. This defeats one of the use-cases of this feature (i.e. detection of a login from a device that doesn't belong to the user logging in).

So...the cookied needs to be authenticated with an HMAC. I also filed #2822732: Add a serial primary key, a hash of data as device_id to teh table, send hash as a coooookie to cover just the parts inside login_history.module for this.

greggles’s picture

This patch is based on #2822732: Add a serial primary key, a hash of data as device_id to teh table, send hash as a coooookie and therefore will fail automated testing so I'm leaving as "needs work" but I basically consider this to be "needs review".

I felt like this should be a sub-module with its own schema, mostly because it records a lot more information about users.

greggles’s picture

Title: Add device detection/ID provided by modules: browscap, fingerprintjs2 » Add device detection/ID provided by modules: fingerprintjs2

I don't think browscap makes sense at this point, so removing it.

greggles’s picture

Status: Needs work » Needs review

And this should now apply and pass tests.

The last submitted patch, 2: 2820919-login-history-fingerprint-D7.patch, failed testing.

greggles’s picture

This is just some small cleanups.

* Capitalizing Login History.
* Adding $account param to the hook for consistency.
* Adding dependency to the info file.

coltrane’s picture

Why is the JS lib data stored? It's a lot of extraneous data without a necessary use case. Could it be optionally stored?

greggles’s picture

Sure, I can see making it optional. It does seem useful to me to store it in general. I can see an upcoming feature to limit the amount of data that gets fingerprinted (e.g. the canvas item is pretty huge and I'm not sure if it's valuable as a distinguishing point or not).

rymcveigh’s picture

I agree with @greggles, it wouldn't hurt to offer the option to save the JS lib data but I think it would be useful to store it in general. Maybe we can store the data by default and offer the option to opt out of storing the data or limit the amount of data that is stored.

Also, should we minimize the JS and maybe create fingerprint2.min.js and lhfingerprintjs2.min.js files?

greggles’s picture

OK, recording the data is now optional and defaults to on.

And using the min js file from the upstream source.

  • greggles committed 4668f43 on 7.x-1.x
    Issue #2820919 by greggles, coltrane: Add device detection/ID provided...
greggles’s picture

Version: 7.x-1.x-dev » 8.x-1.x-dev
Status: Needs review » Patch (to be ported)

OK, committed, so on to 8.x.

krem’s picture

I am trying to install this patch on drupal 8 using
"composer require drupal/login_history:1.x-dev" but I do not see fingerprint data in login history report.

Do I have to install the patch separately ? Thank you

greggles’s picture

For Drupal 7 there is a sub-module that provides this feature since it is a bit different from the main module, so you do need to add it separately.

krem’s picture

Thanks for the reply, I downloaded the D7 version and I get it now... will have to study how to adapt the sub module to drupal 8, hopefully it won't be too difficult.

DrupalDope’s picture

@krem

hello, I would be interested to know where you got with this module?

Prashant.c’s picture

Do you have any plans to port this to the latest version of the module?