提升 Chrome 扩展程序的权限

30

我们目前在Chrome网上应用商店有许多用户的扩展程序。我们目前请求访问foo.site.com,但现在我们想更新权限,以便获得bar.site.com的访问权限。

据我了解,如果我们推送一个新的更新(将新扩展版本发布到Chrome Web Store),需要这两个权限,那么现有用户将被禁用扩展程序,直到他们手动重新启用为止。在更新后下载扩展程序的新用户将没有问题,并获得这两个权限。然而,禁用我们现有的用户不是一个选项。

有什么方法可以绕过这个问题吗?

我们已经研究了可选权限,这将解决现有用户的问题(我们只需要求他们点击一个按钮来升级权限,然后就可以继续使用)。然而,对于新用户,他们不仅需要安装扩展程序,还需要接受可选权限,这很麻烦。是否有任何方法可以让新用户在安装时接受所有权限(必需和可选)?


4
你并没有真正阅读问题,是吗? - aloo
2
我正在处理这个问题:“然而,禁用我们当前的用户不是一个选项。有什么解决办法吗?” - Brian Driscoll
3
似乎能够在安装时声明一些可选权限以供新用户请求是一个有用的功能。请将其归档在http://crbug.com/new?您还可以考虑是否有意义将所有权限转换为可选权限,以便您可以请求一次,而不是每次安装都需要请求,或者是否可以使用beta版本的activeTab权限(http://developer.chrome.com/beta/extensions/activeTab.html)来代替始终访问bar.site.com。 - Jeffrey Yasskin
4个回答

8

是的,有解决办法。 您将新权限设置为可选,然后在用户使用新功能之前请求该权限。 这可以100%地解决问题。

以下是您要添加到清单中的内容:

"permissions": ["tabs","http://*/*","https://*/*"],

之后,您可以使用:

chrome.permissions.request 

并且

chrome.permissions.contains

1
对于新用户,他们需要接受安装扩展的权限并接受另一组权限。 - aloo
@Gabriele 但是,chrome.permissions.request必须在“用户手势”内调用,对吗?你用了什么用户手势来实现这个?如果我想让它在用户加载特定网页时发生怎么办? - Keven Wang
在我的情况下,我有一个小的设置面板,它被注入到页面中。当你切换它时,它会要求权限。我认为它比那更复杂,并且需要使用消息。我制作的扩展名叫做 HN Special,您可以在 GitHub 上找到它。尝试谷歌它 :) - kettlepot
@GabrieleCirulli 正是我在寻找的。谢谢! - Keven Wang
2
有没有办法让我的老用户只获得可选的权限弹窗,而新用户仅在安装扩展时获得一次,而不是两次 - 一次在安装时,另一次在使用这些可选功能时。 - Nakul

5
面对与我的扩展程序相同的问题,我在寻找同样的问题时找到了这篇文章。有一个更新似乎在某些情况下是可以接受的。
根据: https://support.google.com/chrome_webstore/answer/1054246http://developer.chrome.com/extensions/permission_warnings.html 上的示例。
似乎更新您的权限确实会禁用您的扩展程序,但它会提示用户关于您的更改,并允许轻松“重新启用”。
也许在您的情况下这不可接受,但在我的情况下,通过默认添加权限来赢得新用户胜过现有用户不重新启用的风险。因为这比以前您的现有用户不知道扩展程序被禁用要好得多...
我知道这篇文章已经很旧了,但由于它是关于这个问题的谷歌搜索结果中排名最高的,所以认为提供更新内容对未来的参考会有好处...

2
有没有一种方法,让我的旧用户只收到可选的权限弹窗,而新用户只在安装扩展时收到一次,而不是两次 - 一次在安装时,一次在使用这些可选功能时。 - Nakul
@Nakul,你可以使用 chrome.permissions.contains 分别检查权限是否已经被授予或者尚未被询问。 - Akansh

5
自chrome 16起,您可以在安装时设置optional_permission并在运行时请求提升的权限。请参见https://developer.chrome.com/extensions/permissions 在manifest.json中:
  {
    "name": "My extension",
    ...
    "optional_permissions": [ "tabs", "http://bar.site.com/" ],
    ...
  }

在popup.json中:
    document.querySelector('#my-button').addEventListener('click', function(event) {
    // Permissions must be requested from inside a user gesture, like a button's
    // click handler.
    chrome.permissions.request({
      permissions: ['tabs'],
      origins: ['http://bar.site.com/']
    }, function(granted) {
      // The callback argument will be true if the user granted the permissions.
      if (granted) {
        doSomething();
      } else {
        doSomethingElse();
      }
    });
  });

1
使用可选权限的方法可以在不禁用现有用户的扩展的情况下添加新的扩展权限,同时确保新用户在安装后被提示接受所需和可选权限。
chrome.permissions.request API 可以请求可选权限,但前提是要有用户操作。满足此要求并仍然提供无缝用户体验的最简单方法是在后台页面中检查权限,并在运行时在弹出窗口中请求可选权限。
权限请求可以在加载扩展之后的后台页面中进行(安装和随后的浏览器启动后)。任何缺少任何权限的现有用户将在重新启动浏览器后被提示接受权限。
以下示例包括:
  • 背景页 JavaScript(background_page.js)
  • 通知弹出窗口 HTML 文件(notification_popup.html)
  • 通知弹出窗口 JavaScript(notification_popup.js)
您还需要在 manifest.json 中声明 "optional_permissions" 才能使示例正常工作。该示例适用于 Chrome Extension 和 Firefox Add-on。

background_page.js

var brwsr = null;
if (typeof chrome != "undefined") {
    brwsr = chrome;
}
else{
    brwsr = browser;
}
var opt_perms = brwsr.runtime.getManifest().optional_permissions; 
var requiredOptionalPermissions = {}
if(typeof opt_perms!="undefined" && opt_perms.length>0){
    var perms = []
    var origins = []
    var re = new RegExp("^(http|https)://", "i");
    for(var i=0; i<opt_perms.length; i++){
        if(opt_perms[i]==="<all_urls>"|| re.test(opt_perms[i])){
            origins.push(opt_perms[i])
        }
        else{
            perms.push(opt_perms[i])
        }
    }
    if(perms.length>0){
        requiredOptionalPermissions.permissions = perms
    }
    if(origins.length>0){
        requiredOptionalPermissions.origins = origins
    }
}
var requiresPermission = ()=>{
// add your code here
}
// check if optional permission exists and request if not
var runFunctionsRequiringOptPermissions = function(requiredPermissions={}, userGesture=false, callback=()=>{}){
    if(typeof requiredPermissions.permissions!="undefined" || typeof requiredPermissions.origins!="undefined"){
        brwsr.permissions.contains(requiredPermissions, function(res) {
            if (!res) {
                // The extension doesn't have the permissions.)
                if(userGesture){
                    brwsr.permissions.request(requiredPermissions, function(granted){
                        if(granted){
                            // perform actions that required the permission
                            requiresPermission()
                        }
                        callback();
                    });
                    return;
                }
                // open the notification popup 
                window.open("notification_popup.html", "extension_popup", "width=530,height=190,status=no,scrollbars=yes,resizable=no,screenY=+"+(screen.height/2-95)+",screenX="+(screen.width/2-265));
            }
            else{
                // perform actions that required the permission
                requiresPermission()
            }
        });
    }
}

runFunctionsRequiringOptPermissions(requiredOptionalPermissions)
// add listener 
brwsr.runtime.onConnect.addListener(function(port) {
    if(port.name == "optionalPermRequestPopup"){
        port.onMessage.addListener(
            function(request, sender, sendResponse) {
                if (request.okButtonClicked === true) {
                    runFunctionsRequiringOptPermissions(requiredOptionalPermissions, true, function(){
                        // callback to close the notification popup
                        port.postMessage({'close':true});
                    })
                    return;
                } 
                port.postMessage({'close':true})
            }
        );      
    }
});

notification_popup.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Extension Name</title>
    <style>
      .container {
        font-size:medium;
        text-align:center;
      }
      .button{
        height: 30px;
        width: 70px;
        background-color: #448be9;
        color: white;
        border-color: #448be9;
        border-width: thin;
        margin-right: 10px;
        float: right;
      }
      .btnCancel{
        background-color: white;
        color: #448be9
      }
      </style>
    </head>
    <body>
    <div class="container">
        <p class='text'>Please upgrade the permissions to enable the latest features.</p>
        <button class="button btnCancel">Cancel</button>
        <button class="button btnOk">OK</button>
    </div>
    <script src="notification_popup.js"></script>
    </body>
</html>

notification_popup.js

var brwsr = null;
if (typeof chrome != "undefined") {
    brwsr = chrome;
}
else{
    brwsr = browser;
}
var port = brwsr.runtime.connect({
    name : "optionalPermRequestPopup"
});
window.addEventListener("load", function(event) {
    var okButtons = document.querySelectorAll(".btnOk");
    okButtons.forEach(function(okButton) {
        okButton.addEventListener("click", function(event) {
            port.postMessage({okButtonClicked: true})
        });
    });
    port.onMessage.addListener(function(request) {
        for (var key in request) {
            switch(key){
                case "close":
                    window.close();
                    break;
                default:
                    break;
            }               
        }
    });
});

这是一个很好的答案,代码也能正常运行,但前提是需要将background.js的第一行从var brws = null;修改为var brwsr = null;我尝试自己编辑代码,但它不允许编辑少于6个字符的内容。 - user280109
在Chrome中成功运行代码后,我尝试在Firefox中测试它,但尽管代码表明它可以在Firefox中工作,但实际上并不行。当我尝试运行它时,在Firefox中会出现以下错误消息:“Unchecked lastError value: Error: permissions.request may only be called from a user input handler”有人有什么想法如何解决这个问题吗?我已经在各种版本的Firefox中尝试过,包括当前稳定版本和Aurora版本,并且在我尝试的所有版本中都收到了相同的错误消息。 - user280109
似乎在Bugzilla上有一个与此行为相关的“漏洞”:https://bugzilla.mozilla.org/show_bug.cgi?id=1392624最终,我找到了一些其他的代码,可以在Firefox中启用可选权限,这里是:https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/permissions/request我将该代码添加到notification_popup.js中,并将事件侦听器附加到按钮上。现在,我只需要看看是否可以让Firefox代码在Chrome上运行... - user280109

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接