Example of the webRequest.onAuthRequired API (#206)

* Example of the webRequest.onAuthRequired API

* Update README, add applications.id to manifest
This commit is contained in:
wbamberg
2017-04-14 13:34:05 -07:00
committed by GitHub
parent ec034f70a2
commit 5dd59a4028
9 changed files with 224 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
# stored-credentials
**Although this add-on uses a stored password to authenticate to a web server,
it should not be taken as an example of how to store or work securely with
passwords. It's only a demonstration of how to use the
[`webRequest.onAuthRequired`](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/webRequest/onAuthRequired) API.**
This add-on uses the [`webRequest.onAuthRequired`](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/webRequest/onAuthRequired) API to log the user into
the demo site at https://httpbin.org/basic-auth/user/passwd using a stored
username and password.
This add-on stores a username and password using the [`storage.local`](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/storage/local) API.
The default value is the correct value
for the demo site:
username: "user"
password: "passwd"
You can change the default values in the add-on's [options page](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Options_pages).
The add-on then uses `webRequest.onAuthRequired` to intercept authentication
requests from the demo site. When it gets
such a request, it fetches the stored credentials and supplies them
asynchronously.
To try out the add-on:
* Before installing the add-on, visit https://httpbin.org/basic-auth/user/passwd,
and see that it asks for a username and password.
* [Install the add-on](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Temporary_Installation_in_Firefox) in Firefox 54 or later.
* Visit https://httpbin.org/basic-auth/user/passwd again, and see that authentication succeeds automatically.

View File

@@ -0,0 +1,48 @@
var target = "https://httpbin.org/basic-auth/*";
var pendingRequests = [];
/*
A request has completed. We can stop worrying about it.
*/
function completed(requestDetails) {
console.log("completed: " + requestDetails.requestId);
var index = pendingRequests.indexOf(requestDetails.requestId);
if (index > -1) {
pendingRequests.splice(index, 1);
}
}
function provideCredentialsAsync(requestDetails) {
// If we have seen this request before,
// then assume our credentials were bad,
// and give up.
if (pendingRequests.indexOf(requestDetails.requestId) != -1) {
console.log("bad credentials for: " + requestDetails.requestId);
return {cancel: true};
} else {
pendingRequests.push(requestDetails.requestId);
console.log("providing credentials for: " + requestDetails.requestId);
// we can return a promise that will be resolved
// with the stored credentials
return browser.storage.local.get(null);
}
}
browser.webRequest.onAuthRequired.addListener(
provideCredentialsAsync,
{urls: [target]},
["blocking"]
);
browser.webRequest.onCompleted.addListener(
completed,
{urls: [target]}
);
browser.webRequest.onErrorOccurred.addListener(
completed,
{urls: [target]}
);

View File

@@ -0,0 +1 @@
The "lock".svg" icon is taken from the Material Core iconset and is used under the terms of its license: https://www.iconfinder.com/iconsets/material-core.

View File

@@ -0,0 +1 @@
<?xml version="1.0" ?><svg height="23px" version="1.1" viewBox="0 0 16 23" width="16px" xmlns="http://www.w3.org/2000/svg" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns" xmlns:xlink="http://www.w3.org/1999/xlink"><title/><desc/><defs/><g fill="none" fill-rule="evenodd" id="Page-1" stroke="none" stroke-width="1"><g fill="#000000" id="Core" transform="translate(-508.000000, -295.000000)"><g id="lock-open" transform="translate(508.000000, 295.500000)"><path d="M8,16 C9.1,16 10,15.1 10,14 C10,12.9 9.1,12 8,12 C6.9,12 6,12.9 6,14 C6,15.1 6.9,16 8,16 L8,16 Z M14,7 L13,7 L13,5 C13,2.2 10.8,0 8,0 C5.2,0 3,2.2 3,5 L4.9,5 C4.9,3.3 6.3,1.9 8,1.9 C9.7,1.9 11.1,3.3 11.1,5 L11.1,7 L2,7 C0.9,7 0,7.9 0,9 L0,19 C0,20.1 0.9,21 2,21 L14,21 C15.1,21 16,20.1 16,19 L16,9 C16,7.9 15.1,7 14,7 L14,7 Z M14,19 L2,19 L2,9 L14,9 L14,19 L14,19 Z" id="Shape"/></g></g></g></svg>

After

Width:  |  Height:  |  Size: 867 B

View File

@@ -0,0 +1,31 @@
{
"description": "Performs basic authentication by supplying stored credentials.",
"manifest_version": 2,
"name": "stored-credentials",
"version": "2.0",
"homepage_url": "https://github.com/mdn/webextensions-examples/tree/master/stored-credentials",
"icons": {
"48": "icons/lock.svg"
},
"applications": {
"gecko": {
"strict_min_version": "54.0a1"
}
},
"background": {
"scripts": ["storage.js", "auth.js"]
},
"options_ui": {
"page": "options/options.html"
},
"permissions": [
"webRequest",
"webRequestBlocking",
"storage",
"https://httpbin.org/basic-auth/*"
]
}

View File

@@ -0,0 +1,23 @@
body {
width: 25em;
font-family: "Open Sans Light", sans-serif;
font-size: 0.9em;
font-weight: 300;
}
.title {
font-size: 1.2em;
margin-bottom: 0.5em;
}
label {
float: right;
}
input {
margin: 0.5em;
width: 200px;
height: 2.5em;
}

View File

@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="options.css"/>
</head>
<body>
<section class="credentials">
<div class="title" >Username and password</div>
<label>Username: <input id="username" type="text"/></label>
<label>Password: <input id="password" type="text"/></label>
</section>
<script src="options.js"></script>
</body>
</html>

View File

@@ -0,0 +1,39 @@
const usernameInput = document.querySelector("#username");
const passwordInput = document.querySelector("#password");
/*
Store the currently selected settings using browser.storage.local.
*/
function storeSettings() {
browser.storage.local.set({
authCredentials: {
username: usernameInput.value,
password: passwordInput.value
}
});
}
/*
Update the options UI with the settings values retrieved from storage,
or the default settings if the stored settings are empty.
*/
function updateUI(restoredSettings) {
usernameInput.value = restoredSettings.authCredentials.username || "";
passwordInput.value = restoredSettings.authCredentials.password || "";
}
function onError(e) {
console.error(e);
}
/*
On opening the options page, fetch stored settings and update the UI with them.
*/
const gettingStoredSettings = browser.storage.local.get();
gettingStoredSettings.then(updateUI, onError);
/*
On blur, save the currently selected settings.
*/
usernameInput.addEventListener("blur", storeSettings);
passwordInput.addEventListener("blur", storeSettings);

View File

@@ -0,0 +1,27 @@
/*
Default settings. Initialize storage to these values.
*/
var authCredentials = {
username: "user",
password: "passwd"
}
/*
Generic error logger.
*/
function onError(e) {
console.error(e);
}
/*
On startup, check whether we have stored settings.
If we don't, then store the default settings.
*/
function checkStoredSettings(storedSettings) {
if (!storedSettings.authCredentials) {
browser.storage.local.set({authCredentials});
}
}
const gettingStoredSettings = browser.storage.local.get();
gettingStoredSettings.then(checkStoredSettings, onError);