12

我正在做一个 Greasemonkey 脚本,它通过 REST API 与 Redmine 票务管理器进行通信。由于用户需要登录才能从 Redmine 获取数据,我需要一种方法来在脚本安装时询问用户他的凭据并将它们保存到脚本中。

这可以在不要求用户直接在脚本本身中编辑值的情况下实现吗?

编辑:
由于这个问题已经有了答案,我将验证下面给出的答案,因为它是一个非常好的框架。

4

1 回答 1

12

这是一个获取和存储登录凭据的框架。 脚本在第一次运行时提示输入信息,并使用GM_setValue().

它还在 Greasemonkey 上下文菜单中添加了两个项目,以允许更改用户名或密码。

// ==UserScript==
// @name     _Autologin, sensitive info framework
// @include  http://YOUR_SERVER.COM/YOUR_PATH/*
// @require  http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// @require  http://crypto.stanford.edu/sjcl/sjcl.js
// @grant    GM_getValue
// @grant    GM_setValue
// @grant    GM_registerMenuCommand
// ==/UserScript==

var encKey  = GM_getValue ("encKey",  "");
var usr     = GM_getValue ("lognUsr", "");
var pword   = GM_getValue ("lognPwd", "");

if ( ! encKey) {
    encKey  = prompt (
        'Script key not set for ' + location.hostname + '. Please enter a random string:',
        ''
    );
    GM_setValue ("encKey", encKey);

    usr     = pword = "";   // New key makes prev stored values (if any) unable to decode.
}
usr         = decodeOrPrompt (usr,   "U-name", "lognUsr");
pword       = decodeOrPrompt (pword, "P-word", "lognPwd");


function decodeOrPrompt (targVar, userPrompt, setValVarName) {
    if (targVar) {
        targVar     = unStoreAndDecrypt (targVar);
    }
    else {
        targVar     = prompt (
            userPrompt + ' not set for ' + location.hostname + '. Please enter it now:',
            ''
        );
        GM_setValue (setValVarName, encryptAndStore (targVar) );
    }
    return targVar;
}

function encryptAndStore (clearText) {
    return  JSON.stringify (sjcl.encrypt (encKey, clearText) );
}

function unStoreAndDecrypt (jsonObj) {
    return  sjcl.decrypt (encKey, JSON.parse (jsonObj) );
}

//-- Add menu commands that will allow U and P to be changed.
GM_registerMenuCommand ("Change Username", changeUsername);
GM_registerMenuCommand ("Change Password", changePassword);

function changeUsername () {
    promptAndChangeStoredValue (usr,   "U-name", "lognUsr");
}

function changePassword () {
    promptAndChangeStoredValue (pword, "P-word", "lognPwd");
}

function promptAndChangeStoredValue (targVar, userPrompt, setValVarName) {
    targVar     = prompt (
        'Change ' + userPrompt + ' for ' + location.hostname + ':',
        targVar
    );
    GM_setValue (setValVarName, encryptAndStore (targVar) );
}

// ADD YOUR CODE TO SET THE USERNAME AND PASSWORD ON THE LOGIN PAGE, HERE.

重要:

  1. 使用用户脚本登录总是存在风险。
  2. 这个框架大大降低了这种风险,但是 Greasemonkey 和 Tampermonkey 可用的存储机制并不安全,并且浏览器供应商CYA 反对存储机密信息。如果坏人同时获得您的用户脚本浏览器数据,那么他可以对您的密码进行逆向工程。当然,如果他有这个,他很可能无论如何都拥有了你的一台机器。
  3. 明智的做法是使用LastPassKeePass等密码管理器。
  4. 绝对最糟糕的事情是将凭据存储在用户脚本本身中。即使是客人也可以看到它们,你会被“黑”,保证。
于 2013-03-07T10:57:17.857 回答