从chrome扩展获取唯一的ClientID?

时间:2014-05-23 06:14:42

标签: javascript google-chrome google-chrome-extension

我正在开发chrome扩展程序。我需要能够将每个客户识别为唯一的客户。

我无法将guid存储在Cookie中,因为cookie可以删除。我需要从系统本身读取一些独特的东西。

现在 - 我知道JS无法访问客户端资源(本地资源)但是 - 这是我的问题:

问题

Chrome扩展程序Js是否提供了获取唯一客户信息的API(我不关心什么数据 - 只要它是唯一的)。

编辑:

只是为了澄清:

将向用户显示一个唯一键(这是他计算机的哈希数据)。此代码将发送给我,我将提供用户将被发送的匹配结果(通过电子邮件),然后 - 他将能够使用该扩展。

(不,并非所有国家/地区都支持通过钱包进行延期付款,我在其中一个国家)

3 个答案:

答案 0 :(得分:52)

为了唯一标识用户,我建议生成随机令牌并将其存储在您的扩展程序的存储空间(chrome.storage)中。当存储中不存在令牌时,必须仅生成一次用户标识。

例如:

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.
    }
});

这种机制依赖于chrome.storage.sync,这是非常可靠的。此存储的ID仅在以下情况下丢失:

  • 用户重新安装扩展程序。卸载扩展程序时将清除本地存储空间。
  • 已超出其中一个存储配额(请阅读documentation)。
    这不会发生,因为唯一的写操作发生在您的扩展的第一次运行。
  • Chrome的存储空间已损坏,无法保存数据。
    即使用户未启用Chrome同步,数据仍会保存在本地。 Chrome的内部存在漏洞导致数据丢失,但这些都是事件。
  • 用户已为您的扩展程序页面打开了开发人员工具并运行了chrome.storage.sync.clear()或类似内容。
    您无法防范拥有该知识的用户弄乱Chrome扩展程序的内部。

如果要唯一标识用户,则前一种方法就足够了。如果您确实想要获取基于硬件的ID,请同时使用chrome.storage.cpuchrome.storage.memory。我没有看到使用这些额外来源的任何好处,因为如果用户更换硬件,它们可以改变,并且它们也不是唯一的(例如,两台相同的笔记本电脑会报告相同的值)。

答案 1 :(得分:5)

正如Xan所说,chrome.identity API可能是您的最佳选择。您可以获取用户的电子邮件地址,并将其用作随机种子,以生成您选择的代码。用户信息还包括一个“id”字段,我认为该字段是唯一的,但我从未见过任何证明这一点的文档。然后,您可以使用chrome.storage.sync API将生成的密钥存储在应用程序的用户在线数据存储中。这样,用户就可以随时随地登录任何设备来访问他们的私钥。

请注意,您必须在应用程序的开发人员控制台中启用oAuth2 api,并在应用清单中包含应用程序密钥和正确的范围。

这是一个粗略的例子:

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 } );
}

答案 2 :(得分:3)

添加到Rob W的answer。在他的方法中,保存的字符串将传播到使用相同Google用户帐户登录的每个Chrome实例 - 包含大量的小型if。

如果您需要唯一标识本地用户个人资料,而不是所有具有相同Google用户的Chrome个人资料,则您希望以相同方式使用chrome.storage.local。但这不是唯一的Chrome安装标识符 - 只是该安装中的配置文件。


还需要注意的是,所有这些数据都不是以任何方式或形式与任何事物联系在一起 - 它只是很有可能是唯一的。但绝对没有什么能阻止用户阅读和克隆他认为合适的数据。在这种情况下,您不能保护客户端。


我认为更安全的方法是使用chrome.identity API来请求和维护脱机(因此,未到期)令牌作为许可证明。用户无法轻松克隆此令牌存储。

我还没有精通OAuth,所以如果有人能指出这个想法有什么问题 - 欢迎他们。