# Pointers for building a plugin for browser fingerprinting

**URL:** https://meta.discourse.org/t/pointers-for-building-a-plugin-for-browser-fingerprinting/49683
**Category:** Development
**Created:** [2016年九月3日 20:56 UTC](https://meta.discourse.org/t/pointers-for-building-a-plugin-for-browser-fingerprinting/49683 "2016-09-03T20:56:29Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![carmalonso](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/carmalonso/32/217790_2.png) [@carmalonso](https://meta.discourse.org/u/carmalonso)
#### Post date: [2016年九月3日 20:56 UTC](https://meta.discourse.org/t/pointers-for-building-a-plugin-for-browser-fingerprinting/49683/1 "2016-09-03T20:56:29Z")

</div>

Based on the discussion from my thread:

> [@Handling trolls with multiple accounts over VPNs](https://meta.discourse.org/t/handling-trolls-with-multiple-accounts-over-vpns/49489):
>
> Hey all, we’re seeing an increase in troll users (usually users that have been suspended in the past for abusing other members) over on our Discourse forum. We can usually establish when it’s a troll account based on their email address and their source IP and deal with it, but sometimes it’s not until they make a thread with more abusive content that we see it isn’t a “real” account. I’ve already tried a few wildcard IP bans based on some DigitalOcean IPs (our trolls tend to use VPNs, most of …

I decided to try my hand at building a plugin that would help prevent suspended users from returning by blocking their browser fingerprint (see [panopticlick.eff.org](https://panopticlick.eff.org/)). My plan for this plugin involves:

- calculating a browser’s fingerprint on plugin initialise (using the [FingerprintJS2](https://github.com/Valve/fingerprintjs2) JavaScript library)

- save it to the database based on the user’s id if it doesn’t already exist (there should be a single object per each fingerprint tied to the user - we capture every unique fingerprint a user logs in with to prevent access to all device in the future)

- on load, query by the calculated fingerprint to see if it is blocked; perform a similar action to an IP block if this is the case, or allow the user to access the site if they’re not blocked.

I’ve made a bit of progress below:  
[https://github.com/carmichaelalonso/discourse-fingerprint-bans](https://github.com/carmichaelalonso/discourse-fingerprint-bans)

Now the tough part for me is the fact I’m completely new to Ember and Rails, so this is taking a bit of getting used to. I’ve based this on other plugins (such as the discourse-staff-notes plugin) to help get a good structure and to learn how this stuff all works.

In `plugin.rb`, I believe I’ve set up a model interaction layer. The model is called by the `saveFingerprint` function in `/assets/javascripts/controllers/fingerprint.js.es6`, and I’m trying to call this function (exported as an action) from the initializer `fingerprint.js.es6` file.

From what I’ve gathered, this is theoretically how I’d call the `saveFingerprint` function from the initializer:

> <https://github.com/carmichaelalonso/discourse-fingerprint-bans/blob/master/assets/javascripts/discourse/initializers/fingerprint.js.es6#L13>

However, `this` is undefined (expected) and I’m not sure how this is declared.

I’d welcome any input/contributions from someone a bit more experienced as to how I should go about this and how

---

<div class="post-metadata">

### Author: ![eviltrout](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/eviltrout/32/5275_2.png) [@eviltrout](https://meta.discourse.org/u/eviltrout)
#### Post date: [2016年九月8日 20:30 UTC](https://meta.discourse.org/t/pointers-for-building-a-plugin-for-browser-fingerprinting/49683/2 "2016-09-08T20:30:08Z")

</div>

> [@carmalonso](#):
>
> However, this is undefined (expected) and I’m not sure how this is declared.

By default in Javascript, when you create a function() closure, you [create a new context](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this) with a new `this`.

Since your sample code above includes two `function()`s, the value of `this` will be overridden both times.

An easy way to get around this is to replace your `function()` with the [ES2015 Arrow](https://babeljs.io/docs/learn-es2015/#arrows-and-lexical-this).

Having said that, even if you do fix it, the value of `this` in the initializer does not have a `this.get('controllers')` in it. You’ll need to look it up on the container, like:

`container.lookup('controller:fingerprint')` instead.

(the container is passed as an argument to the initializer).

---

<div class="post-metadata">

### Author: ![riking](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/riking/32/170938_2.png) [@riking](https://meta.discourse.org/u/riking)
#### Post date: [2016年九月10日 22:44 UTC](https://meta.discourse.org/t/pointers-for-building-a-plugin-for-browser-fingerprinting/49683/3 "2016-09-10T22:44:51Z")

</div>

Another tip: you should store the data in the PluginStore.

---

<div class="post-metadata">

### Author: ![carmalonso](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/carmalonso/32/217790_2.png) [@carmalonso](https://meta.discourse.org/u/carmalonso)
#### Post date: [2016年九月11日 11:52 UTC](https://meta.discourse.org/t/pointers-for-building-a-plugin-for-browser-fingerprinting/49683/4 "2016-09-11T11:52:21Z")

</div>

I think that was what I was aiming to do (basing it on the Staff Notes plugin as it appeared to do the same)

---

<div class="post-metadata">

### Author: ![codinghorror](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/codinghorror/32/110067_2.png) [@codinghorror](https://meta.discourse.org/u/codinghorror)
#### Post date: [2018年七月24日 20:00 UTC](https://meta.discourse.org/t/pointers-for-building-a-plugin-for-browser-fingerprinting/49683/5 "2018-07-24T20:00:05Z")

</div>

Did you make any progress on this? [We’re sponsoring it](https://meta.discourse.org/t/build-a-browser-fingerprinting-plugin/93037), if so.
