mirror of
https://github.com/mdn/webextensions-examples.git
synced 2026-04-16 06:18:35 +02:00
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:
32
stored-credentials/README.md
Normal file
32
stored-credentials/README.md
Normal 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.
|
||||
|
||||
48
stored-credentials/auth.js
Normal file
48
stored-credentials/auth.js
Normal 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]}
|
||||
);
|
||||
1
stored-credentials/icons/LICENSE
Normal file
1
stored-credentials/icons/LICENSE
Normal 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.
|
||||
1
stored-credentials/icons/lock.svg
Normal file
1
stored-credentials/icons/lock.svg
Normal 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 |
31
stored-credentials/manifest.json
Normal file
31
stored-credentials/manifest.json
Normal 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/*"
|
||||
]
|
||||
}
|
||||
23
stored-credentials/options/options.css
Normal file
23
stored-credentials/options/options.css
Normal 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;
|
||||
}
|
||||
22
stored-credentials/options/options.html
Normal file
22
stored-credentials/options/options.html
Normal 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>
|
||||
39
stored-credentials/options/options.js
Normal file
39
stored-credentials/options/options.js
Normal 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);
|
||||
27
stored-credentials/storage.js
Normal file
27
stored-credentials/storage.js
Normal 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);
|
||||
Reference in New Issue
Block a user