I'm developing chrome extension. I need the ability to identify each client as a unique client.
I can't store guid in a cookie since cookie can be deleted. I need something to be read from the system itself which is unique.
Now - I know that JS doesn't has access to client resources ( local resources) but - and here is my question :
Question
Does chrome extensions Js's provide API for getting unique client information ( I dont care what data - as long as it is unique).
Edit :
Just to clarify :
The user will be shown a unique key ( which is a hash data of his computer). this code will be sent to me , and I will provide matching result which the user will be sent (via email) and only then - he will be able to use the extension.
(no , not all countries support extension payment via wallet , im at one of those countries)
To uniquely identify a user, I would suggest to generate a random token and store it in your extension's storage (chrome.storage). The userid has to be generated only once, when the token does not exist in storage.
For example:
function getRandomToken() {
// E.g. 8 * 32 = 256 bits token
var randomPool = new Uint8Array(32);
crypto.getRandomValues(randomPool);
var hex = '';
for (var i = 0; i < randomPool.length; ++i) {
hex += randomPool[i].toString(16);
}
// E.g. db18458e2782b2b77e36769c569e263a53885a9944dd0a861e5064eac16f1a
return hex;
}
chrome.storage.sync.get('userid', function(items) {
var userid = items.userid;
if (userid) {
useToken(userid);
} else {
userid = getRandomToken();
chrome.storage.sync.set({userid: userid}, function() {
useToken(userid);
});
}
function useToken(userid) {
// TODO: Use user id for authentication or whatever you want.
}
});
This mechanism relies on chrome.storage.sync, which is quite reliable. This stored ID will only be lost in the following scenarios:
The user re-installs the extension. Local storage will be cleared when uninstalling the extension.
One of the storage quotas has been exceeded (read the documentation).
This is not going to happen because the only write operation occurs at the first run of your extension.
Chrome's storage gets corrupted and fails to save the data.
Even if the user does not have Chrome Sync enabled, data will still be saved locally. There have been bugs with Chrome's internals that resulted in data loss, but these are incidents.
The user has opened the developer tools for your extension page and ran chrome.storage.sync.clear() or something similar.
You cannot protect against users who possess the knowledge to mess with the internals of Chrome extensions.
The previous method is sufficient if you want to uniquely identify a user. If you really want to get a hardware-based ID, use chrome.storage.cpu and chrome.storage.memory as well. I don't see any benefits in using these additional sources though, because they can change if the user replaces hardware, and they are not unique either (two identical laptops would report the same values, for instance).
As Xan suggested, the chrome.identity API is probably your best choice. You can get the users e-mail address and use that as a random seed to generate a code of your choosing. The user info also includes an "id" field which I believe is unique but I haven't ever seen any documentation that substantiates that. You can then use the chrome.storage.sync API to store the generated key in the users online data storage for your app. This way the user will be able to access their private key whenever and where ever they log in on any device.
Please note that you will have to enable the oAuth2 api's in the developers console for your application and include the application key and proper scopes in your app manifest.
Here is a crude example:
function getUserInfo (interactive, callback )
{
var xmlhttp = new XMLHttpRequest();
var retry = true;
var access_token;
getToken();
/**
* Request the Auth Token
*/
function getToken()
{
chrome.identity.getAuthToken( { 'interactive': interactive }, function (token) {
if ( chrome.runtime.lastError )
{
console.log( "ERROR! " + chrome.runtime.lastError.message );
return;
}
if ( typeof token != 'undefined ')
{
access_token = token;
sendRequest( );
}
else
callback( );
});
}
function sendRequest()
{
xmlhttp.open('GET', 'https://www.googleapis.com/userinfo/v2/me' );
xmlhttp.setRequestHeader('Authorization','Bearer ' + access_token );
xmlhttp.onload = requestComplete;
xmlhttp.send();
}
function requestComplete()
{
if ( this.status == 401 && retry )
{
retry = false; // only retry once
console.log( "Request failed, retrying... " + this.response );
}
else
{
console.log( "Request completed. User Info: " + this.response );
callback(null, this.status, this.response );
var userInfo = JSON.parse( this.response );
storeUniqueKey( userInfo );
}
}
}
function storeUniqueKey( info )
{
var key;
// TODO: Generate some key using the user info: info.loginName
// user info here contains several fields you might find useful.
// There is a user "id" field here which is numeric and I believe that
// is a unique identifier that could come in handy rather than generating your
// own key.
...
chrome.storage.sync.set ( { user_key: key } );
}
To add to Rob W's answer. In his method, the saved string would propagate to every Chrome instance signed in with the same Google user account - with a lot of big and small if's.
If you need to uniquely identify a local user profile, and not all Chrome profiles with the same Google user, you want to employ chrome.storage.local in the same manner. This will NOT be a unique Chrome install identifier though - only a profile within that install.
What also needs to be noted is that all this data is not in any way or form tied to anything - it just has a good probability of being unique. But absolutely nothing stops user from reading and cloning this data as he sees fit. You cannot, in this scenario, secure the client side.
I'm thinking that a more secure way would be to use chrome.identity API to request and maintain an offline (therefore, not expiring) token as proof of license. The user cannot easily clone this token storage.
I'm not versed in OAuth yet, so if anyone can point out what's wrong with this idea - they are welcome to.
We can also use Crypto.randomUUID() for generating a UUID and then save it to web storage. Refer to MSDN for details this API.
let uuid = self.crypto.randomUUID();
console.log(uuid); // for example "36b8f84d-df4e-4d49-b662-bcde71a8764f"
Related
I've got a nice DeviceMotionEvent request all working for Safari (or other browsers that require the permission), something along these lines:
// on click of a button
DeviceMotionEvent.requestPermission()
.then(response => {
if (response == 'granted') {
// do my thing
}
})
.catch(function(error) {
console.log(error);
// do my other thing
});
And thats working great. But when a user goes to a new page, they have to request the permission again. Obviously I'm calling 'requestPermission' again, so of course they would do.
How do I find out if permission has already been granted? Or is permission granted on a page by page basis (rather than session / site basis)?
I could store the response in localstorage or something, but would prefer something along the lines of:
DeviceMotionEvent.permissionStatus
Or something?
I think you only option is to build a single page application and use the history.pushState() to update the location in the browser, when you wish to ‘change pages’.
Edited:
You can use the Web Storage API with the following two mechanisms:
sessionStorage
localStorage
As the names imply, these two interfaces are ideal for session-based data or if you want to persist state even after the connection is closed.
You should be able to check whether permissions have been granted using the devicemotion eventListener. Baring in mind you have to push a button or similar to run DeviceMotionEvent.requestPermission()
eg.
let hasOrientationControls = false;
window.addEventListener("devicemotion", () => {
hasOrientationControls = true;
});
// then when the button is pressed we can request permissions if we need
onButtonPressed () => {
if (hasOrientationControls) return;
else DeviceMotionEvent.requestPermission();
}
I've also used this
isVRReady = window.DeviceOrientationEvent && "ontouchstart" in window;
I am automating load tests using Jmeter, I have very simple page where I'm putting data into input fields and buttons clicks.
I see following response data:
function handleBack() { var programGroup = document.getElementById('programGroupName').value; if(programGroup == 'SE') { var url = $('#fundraiserPageURL').val();; var index = url.lastIndexOf('/'); if (index > 0) { newurl = url.substring(0, index); } var action = newurl + "/decodeCheckOutDetails.action"; encodeCheckoutFRHttpSession(action, 'backFormIdFR'); } }
Visit LLS.ORG
0
VISIT LLS.ORG
Sorry! the session expired, please try again.
Make sure to upgrade to latest JMeter version (JMeter 3.3 as of now) as looking into i.e. HTTP Cookie Manager GUI it appears you're sitting on the outdated version. Or at least make sure you use the following settings in order to comply with the RFC 6265:
Implementation: HC4CookieHandler
Policy: standard
along with HttpClient4 implementation in the HTTP Request Defaults.
Also double check you performed correlation of all dynamic values using suitable JMeter PostProcessors.
I'm creating a Google chrome extension. For some functionality, I need user's system login name (no password). By using JavaScript, it is not possible to do so.
Some suggest NPAPI, but I have no idea about it, so I quit.
Next thing I'm trying to get user name in Chrome Browser. But still no success.
I try to use some thing like:
var currentUser;
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(data) {
if (xhr.readyState == 1) {
currentUser = null;
if (xhr.status == 200)
{
var re = new RegExp(/<b class="?gb4"?>[\s]*([^<]+#[^<]+) <\/b>/i);
var m = re.exec(xhr.responseText);
if (m && m.length == 2) {
currentUser = m[1];
}
}
console.log("Currently logged user (on google.com): " + currentUser);
}
};
xhr.open('GET', ' https://myaccount.google.com/?pli=1', false);
xhr.send(); `
still no success.
My whole agenda is to get user name (either desktop login name or Chrome login name), and I'm not able to get it.
I need to send this username as parameter to my service, as user name works as primary key.
First off, you say that you need this login information to identify a user, using it as a primary key.
That automatically disqualifies system login names: they are not unique.
Now, let's get back to logged-in Chrome user. Google Account is reasonably unique.
There are two approaches to take here.
Chrome's chrome.identity API can provide both the email and, maybe better for your purposes, a unique ID for the account.
You will need "identity" and "identity.email" permissions. Then:
chrome.identity.getProfileUserInfo(function(userInfo) {
/* Use userInfo.email, or better (for privacy) userInfo.id
They will be empty if user is not signed in in Chrome */
});
An alternative approach is to use Google's OAuth on your service. Again, see the chrome.identity documentation.
Chrome.identity has a method getProfileUserInfo but it gives out the details of only primary user.
There is an alternative:
When you open chrome, you launch onto the home screen and you should be able to see a circle on the top right corner which shows image of logged in user. You can access that using DOM. Once you do that you will be able to get information about all the logged in users.
I am working on Weemo JS API for video conference.
1) I need some technical help for identify online user for conference.
2) How can i pass data from caller to callee?
3) How online user can disconnected from cloud?
please provide some technical ref for same.
Thanks.
You can know if a user is online or not by using the weemo.getStatus('USER_UID') method.
(void) getStatus('USER_UID')
When 'USER_UID' is the value of the target user Uid (String).
You will need to use the weemo.onGetHandler(name, obj) callback to catch the answer.
Here is an example of how to get the status of a user with a 'USER_ID' equal to 'userTestStatus':
var weemo = new Weemo('AppId', 'Token', 'Type');
weemo.onGetHandler = function(name, obj) {
switch(name) {
case 'status':
var uid = obj.uid;
if(obj.value == 0) {
console.log("User "+uid+" is offline with a status "+obj.value);
} else {
console.log("User "+uid+" is online with a status "+obj.value);
}
break;
}
};
weemo.onConnectionHandler = function(message, code) {
console.log("Connection Handler : " + message + ' ' + code);
switch(message) {
case 'sipOk':
weemo.getStatus('userTestStatus');
break;
}
};
weemo.initialize();
FYI: In this example I used the getStatus in the onConnectionHandler after receiving a "sipOk" because I want to make sure that my user is completly connected before runing a getStatus. Once you user is connected to the Weemo Cloud you can execute a getStatus out of the onConnectionHandler.
Once connected you can disconnect your user by using the weemo.reset() method. This will disconnect your user from the Weemo cloud.
(void) reset()
The reset function is used in order to properly disconnect the user from the cloud, and be able to connect to the real-time platform with other credentials.
You can find more details in the documentation and sample code available on the Weemo github here.
You can also find the full Weemo JavaScript API here
I was wondering if there is a javascript or html code that can redirect to another web page if the user comes 3 times on the same webpage? I see this sometimes on websites that have a trial version.
Thank you for your answer.
As jods said, doing it client-sided (JavaScript) is insecure. A simple 'clean' of your browser history undo's the trick..
But here's a quick example how you can do it with localStorage:
/*
use this to reset the code:
localStorage.setItem('visited', 0);
*/
var views = localStorage.getItem('visited');
views = (views===undefined)? 1 : parseInt(views)+1;
if (views<=3)
{
localStorage.setItem('visited', views);
document.write('You visited this page for the: ' + views + ' time!');
}
else
{
document.write('You can only view it 3 times!');
}
This is better handled server-side. I don't know what technology you use (PHP, .NET, Java), but the server can easily check the IP address of the client and return a different answer after 3 times, like a redirect response.
Handling it client-side is possible as suggested with cookies or localStorage, but that's very ineffective if your goal is security (e.g. a trial restriction). Cookies and localStorage are trivial to clear and the user grants himself 3 new free accesses.
You cannot do this solely with Javascript, you would have to communicate with the server and implement it that way.
If you would like to replace IP Address with Device then you could use localStorage or a cookie.
Here's an example using localStorage
var count = Number( localStorage.visitCount );
if(isNaN(count)) {
localStorage.visitCount = 1
} else {
localStorage.visitCount++
}
if( +localStorage.visitCount === 3 ) {
window.location.replace('http://stackoverflow.com')
}