![](/img/trans.png)
[英]app.use inside a promise (bookshelf.js & express-basic-auth)
[英]Basic Authentication using Express and express-basic-auth package. Trigger login and logout with javaScript
要注銷使用基本身份驗證登錄的用戶,我正在嘗試遵循以下建議: link1 link2
我正在使用express-basic-auth
來保護我的應用程序中的一些路由。 使用它的受保護路由的示例如下:
const basicAuth = require('express-basic-auth');
const protect = basicAuth({
users: { 'admin': 'secret' },
challenge: true
})
app.get('/protected', protect, function(req, res) {
console.log("authorization header ", req.headers.authorization);
console.log("user ", req.auth);
res.send('Success!');
});
在basicAuth
中使用challenge: true
我們會彈出一個輸入用戶名和密碼的窗口。 如果輸入的信息正確,我們就會Success!
寫在屏幕上。
當我想注銷用戶時出現問題。 我研究並發現基本身份驗證不是圍繞注銷建立的,但有一些黑客方法可以做到這一點。
要注銷,我們基本上需要使用錯誤的憑據登錄。 我們不能要求用戶這樣做,所以我想編寫一個 JavaScript 片段,該片段會使用錯誤的憑據登錄並將該代碼鏈接到注銷按鈕。
要注銷,我創建了一個注銷按鈕,並使用帶有GET
方法和錯誤憑據的fetch
強制注銷。 代碼如下:
const logoutLink = document.getElementById("logout");
logout.addEventListener("click", handleLogoutClick)
function handleLogoutClick() {
// Wrong credentials
let username = 'admin';
let password = 'passwd';
let url = `http://localhost:3000/protected`; // url cannot have credentials
let headers = new Headers();
headers.append('Content-Type', 'text/json');
headers.set('Authorization', 'Basic ' + btoa(username + ":" + password));
fetch(url, {method:'GET',
headers: headers})
.then(response => {
if (!response.ok) throw new Error(response.status);
return response.json();})
.then(data => {console.log("Data is", data)})
.catch(err => {console.log("Error is", err)})
上面的代碼片段在 Chrome 上注銷用戶時有效,但在 Firefox 中無效。
在我的瀏覽器中,如果我想注銷用戶並且我這樣做: http://user:wrongPassword@localhost:3000/protected
,那么它會注銷用戶(適用於 Chrome 和 Firefox)
However, I can't make a fetch
request to http://user:wrongPassword@localhost:3000/protected
URL so I have to make a request to http://localhost:3000/protected
and passed the credentials as a header.
另外為了測試注銷請求可能有什么問題,我嘗試使用 javascript 發出登錄請求。 當我在瀏覽器中看到console.log
語句以及我在運行應用程序的終端上看到的語句時,它似乎有效(獲得狀態200
)。 但是當我嘗試訪問受保護的路由時,我會彈出basicAuth
彈出窗口以再次輸入憑據。 (如果我在瀏覽器中手動登錄,它不會再次要求登錄憑據)
登錄代碼(這似乎在我返回的 200 狀態請求方面有效)但實際上並不有效,如下所示:
function userForm() {
const loginForm = document.getElementById('login-form');
loginForm.addEventListener("submit", handleFormSubmit)
function handleFormSubmit(e) {
e.preventDefault();
const formData = new FormData(document.querySelector('form'));
const formObject = {}
for (let pair of formData.entries()) {
formObject[pair[0]] = pair[1];
}
console.log(formObject);
const {username, password} = formObject;
const url = `http://localhost:3000/protected`;
let headers = new Headers();
headers.append('Content-Type', 'text/json');
headers.set('Authorization', 'Basic ' + btoa(username + ":" + password));
(async () => {
try {
const response = await fetch(url, {
method: 'GET',
headers: headers
});
console.log("response is", response);
if (response.status === 200) {
window.location.href = url;
}
} catch (error) {
console.log("An error occured in form submission");
}
})(url, headers);
}
}
userForm();
我們得到一個200
的response.status
但是當瀏覽器被重定向到受保護的路由時,我會彈出一個輸入憑據。 當我使用 vanilla JS 對受保護的路由進行fetch
調用時,我可以看到打印到終端的授權標頭和用戶值(來自console.log
app.get('/protected', protect, function(req, res) {}
我知道basicAuth
不是在生產中使用的東西。 但我想知道為什么這樣的登錄不起作用。 還有為什么注銷不適用於 firefox 但適用於 chrome。 還有一些我可以參考的資源可能會為我清除basicAuth
。 package exxpress-basic-auth
在這方面不是很清楚。
關閉瀏覽器或刷新瀏覽器會注銷用戶。 但是,如果我可以為注銷按鈕編寫腳本,也許還可以為登錄編寫腳本,那就更好了。
在搜索和試驗之后,我發現了如何使用 javascript 注銷使用基本身份驗證登錄的用戶,以及為什么我上面使用的方法似乎有效但實際上並沒有奏效。
Javascript 代碼用於注銷有效的用戶(在 chrome 和 firefox 中檢查)。
const logoutLink = document.getElementById("logout");
logout.addEventListener("click", handleLogoutClick)
function handleLogoutClick() {
// url for protected route
const url = 'http://localhost:3000/users'
// wrong credentials to remove
// to trigger a login with wrong credentials
const username = 'fakeUser';
const password = 'randomPassword';
var http = new XMLHttpRequest();
// xhr request with wrong credentials
// so as to flush out the saved correct credentials
http.open("get", url, false, username, password);
http.send("");
// status 401 is for accessing unauthorized route
// will get this only if attempt to flush out correct credentials was successful
if (http.status === 401) {
alert("You're logged out now");
window.location.href = "/";
} else {
alert("Logout failed");
}
}
上述方法之所以有效,是因為它建立了一個瀏覽器 session。
Javascript 注銷我們使用headers.set('Authorization', 'Basic ' + btoa(username + ":" + password));
不起作用,因為該方法僅適用於該特定請求。
這就是為什么在headers
中使用帶有錯誤憑據的方法會引發401
(未經授權的請求),但僅針對該特定請求。 由於它僅針對該特定請求發送錯誤的用戶憑據,因此無法清除正確的用戶憑據並注銷用戶。
只是想添加到 AJ 的答案,因為它對我有用。 我想阻止后退按鈕訪問頁面,所以我在我的快速后端添加了這些標題,這阻止了緩存版本的加載:
res.header('Cache-Control', 'private, no-cache, no-store, must-revalidate');
res.header('Expires', '-1');
res.header('Pragma', 'no-cache');
這是取自這個答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.