javascript - Web 扩展身份 token 返回 403

标签 javascript firefox-addon-webextensions

帐户信息: 用户名:testAccount 密码password1234

我使用的是 Firefox Developer Edition,因为它支持身份调用。 我收到来自验证的 403 错误。 “TypeError:尝试获取资源时出现网络错误。”“403 Forbidden”我做错了什么,导致无法继续下一步。

Manifest.json 文件内容

    {

  "manifest_version": 2,
  "name": "Lewp",
  "applications": {
    "gecko": {
      "id": "addon@lewp.com"
    }
  },
  "version": "1.0",

  "description": "Test project to check Oauth2",

  "icons": {
    "48": "icons/link-48.png"
  },

  "browser_action": {
  "browser_style": true,
  "default_icon": {
    "16": "icons/link-48.png",
    "32": "icons/link-48.png"
  },
  "default_title": "Whereami?"
},

  "permissions": [
    "activeTab",
    "alarms",
    "bookmarks",
    "browsingData",
    "contextMenus",
    "contextualIdentities",
    "cookies",
    "downloads",
    "downloads.open",
    "history",
    "identity",
    "idle",
    "management",
    "notifications",
    "nativeMessaging",
    "sessions",
    "storage",
    "tabs",
    "topSites",
    "webNavigation",
    "webRequest",
    "webRequestBlocking"
  ],

  "options_ui": {
    "page": "settings/options.html"
  },

  "background": {
  "scripts": ["core.js", "settings/background-script.js", "settings/jquery-3.1.1.min.js"]
},

  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "exclude_matches": ["*://*.lewp.com/*", "*://*.google.com/*"],
      "js": ["settings/borderify.js"]
    }
  ],
   "default_locale": "en"

}

背景脚本.js

function onError(error) {
  console.log(`Error: ${error}`);
}

const REDIRECT_URL = browser.identity.getRedirectURL();
const CLIENT_ID = "f3dddddasdfaasdfvfdggfsfdg";
const CLIENT_SECRET = "4c7f6f8fa93d59c45502c0ae8c4a95b";
const AUTH_URL =
`http://lewp.com/oauth/authorize
?client_id=${CLIENT_ID}
&response_type=code
&redirect_uri=${encodeURIComponent(browser.identity.getRedirectURL())}`;
const VALIDATION_BASE_URL="http://lewp.com/oauth/access_token";

function extractAccessToken(redirectUri) {
  let m = redirectUri.match(/[#\?](.*)/);
  if (!m || m.length < 1)
    return null;
  let params = new URLSearchParams(m[1].split("#")[0]);
  return params.get("code");
}

function extractState(redirectUri) {
  let m = redirectUri.match(/[#\?](.*)/);
  if (!m || m.length < 1)
    return null;
  let params = new URLSearchParams(m[1].split("#")[0]);
  return params.get("state");
}

/**
Validate the token contained in redirectURL.
This follows essentially the process here:
https://developers.google.com/identity/protocols/OAuth2UserAgent#tokeninfo-validation
- make a GET request to the validation URL, including the access token
- if the response is 200, and contains an "aud" property, and that property
matches the clientID, then the response is valid
- otherwise it is not valid
Note that the Google page talks about an "audience" property, but in fact
it seems to be "aud".
*/
function validate(redirectURL) {
  const accessToken = extractAccessToken(redirectURL);
  const state = extractState(redirectURL);

  if (!accessToken) {
    throw "Authorization failure";
  } else {

    let accessTokenSetting = {
      accessToken: accessToken
    }

    // store the objects
    let setting = browser.storage.local.set({accessTokenSetting});
    // just check for errors
    setting.then(null, onError);

    let accessTokenGot = browser.storage.local.get("accessTokenSetting");
    accessTokenGot.then(onGotToken, onError);

    function onGotToken(item) {
      console.log(item.accessTokenSetting.accessToken);
    }


  }
  const validationURL = `${VALIDATION_BASE_URL}?code=${accessToken}&state=${state}`;
  const validationRequest = new Request(VALIDATION_BASE_URL, {
    method: "POST",
    body : [
      'grant_type=authorization_code',
      'client_id='+ CLIENT_ID,
      'client_secret='+ CLIENT_SECRET,
      'redirect_uri='+ encodeURIComponent(REDIRECT_URL),
      'code='+ accessToken
    ].join('&'),
    headers: {"content-type": "application/x-www-form-urlencoded",
              "code": accessToken}
    // state: "432123",
    // dataType: "json",
    // contentType: "json"
  });

  function checkResponse(response) {
    return new Promise((resolve, reject) => {
      if (response.status != 200) {
        console.log('Token validation error');
        reject("Token validation error");
      }
      response.json().then((json) => {
        // if (json.client_id && (json.client_id === CLIENT_ID)) {
        if (json.access_token) {
          resolve(accessToken);
        } else {
          console.log("Token validation error");
          reject("Token validation error");
        }
      });
    });
  }

  return fetch(validationRequest)
  .then(checkResponse)
  .catch(logError);
}

/**
Authenticate and authorize using browser.identity.launchWebAuthFlow().
If successful, this resolves with a redirectURL string that contains
an access token.
*/

//'http://localhost:8000/oauth/authorize?client_id=f3dddddasdfaasdfvfdggfsfdg&redirect_uri=https://e188f182e3ca96050362eff7355ace5274d6f59e.extensions.allizom.org/&response_type=code'
function authorize() {
  if(typeof chrome == "undefined")
    return browser.identity.launchWebAuthFlow({
      interactive: true,
      url: AUTH_URL
    });
  else
    return new Promise(function(resolve,reject){
      browser.identity.launchWebAuthFlow({
        interactive: true,
        url: AUTH_URL
      }, (responseUrl)=>{
        if(chrome.runtime.lastError)
          reject(chrome.runtime.lastError);
        else
          resolve(responseUrl);
      });
    })
}

function getAccessToken() {
  return authorize().then(validate).catch(logError);
}

function logError(error) {
  console.error(`Error: ${error} `);
}

/**
When the button's clicked:
- get an access token using the identity API
- use it to get the user's info
- show a notification containing some of it
*/
  // getAccessToken()
  //   .then(notifyUser)
  //   .catch(logError);



  /*
  Log that we received the message.
  Then display a notification. The notification contains the URL,
  which we read from the message.
  */
  function notify(message) {
    var title = browser.i18n.getMessage("notificationTitle");
    var content = browser.i18n.getMessage("notificationContent", message.url);
    browser.notifications.create({
      "type": "basic",
      "iconUrl": browser.extension.getURL("icons/link-48.png"),
      "title": title,
      "message": content
    });
  }

  /*
  Assign `notify()` as a listener to messages from the content script.
  */
  browser.runtime.onMessage.addListener(notify);


  function sendMessageToTabs(tabs) {
    for (let tab of tabs) {
      browser.tabs.sendMessage(
        tab.id,
        {greeting: "Hi from background script"}
      ).then(response => {
        console.log("Message from the content script:");
        console.log(response.response);
      }).catch(onError);
    }
  }



//actual start to code
//set global data variable
var data = {};

function getAccessToken() {
  return authorize().then(validate).catch(logError);
}

function onGotToken(item) {
  var promise = new Promise(function(resolve, reject){
    data.token = item.accessTokenSetting.accessToken;
    resolve();
   });
  return promise;
};

function fetchToken(item) {
    //getAccessToken from backend need to modify it so it waits until after
    //call to get Access Token
  var promise = new Promise(function(resolve, reject){
    var accessTokenGot = browser.storage.local.get("accessTokenSetting");
    accessTokenGot.then(onGotToken, logError).then(resolve, reject);
  });
  return promise;
}

function fetchLewps(item) {
  var promise = new Promise(function(resolve, reject){
    resolve();
  });
  return promise;
}

function fetchLewpsAPI(item) {
  var promise = new Promise(function(resolve, reject){
    var url = 'http://lewp.com/api?access_token='+data.token;
    fetch(url, {
        method: 'GET',
        headers: {    "authorization": "Bearer "+data.token,
                      "content-type": "application/x-www-form-urlencoded"}
      })
      .then(json)
      .then(function (data) {
        console.log('Request succeeded with JSON response', data);
        resolve();
      })
      .catch(function (error) {
        console.log('Request failed', error);
      });
  });
  return promise;
}

//on click of browser toolbar button
  browser.browserAction.onClicked.addListener(() => {
    //get authorized
    getAccessToken()
      .then(fetchToken)
      .then(fetchLewps)
      .then(fetchLewpsAPI)
      .catch(logError);

    //filler that sends notification
    browser.tabs.query({
      currentWindow: true,
      active: true
    }).then(sendMessageToTabs).catch(onError);
  });

最佳答案

网络错误大多发生在没有连接到互联网或API链接不正确的情况下。

关于javascript - Web 扩展身份 token 返回 403,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43728391/

相关文章:

javascript - 使用 Angular 和 TypeScript 构建 WebExtension

javascript - 如何从内容脚本访问后台脚本变量

javascript - 根据数字数组 : Another version (Not duplicate! 对字符串数组进行排序!)

javascript - jQuery : Remove created element if CLICKED button value is xxx

javascript - 需要样式表并将它们作为带有 browserify 的链接标记注入(inject) html

javascript - 有没有办法附加到对象 URL 或以其他方式创建流作为 URL?

javascript - Firefox WebExtension内容脚本: TypeError: browser.运行时未定义

javascript - Safari Javascript Date() NaN 问题 (yyyy-MM-dd HH :mm:ss)

javascript - 在 Jquery attr 上使用此类

javascript - Web 扩展。在个人扩展中使用第三方 (npm) 软件包(不适用于发行版)