Я пытаюсь создать простую форму входа в систему, используя Node / Express / Passport / Javascript с обычной аутентификацией, но не могу заставить ее работать. Я хочу иметь страницу, где вы вводите свои учетные данные и нажимаете «Войти». Если эти учетные данные верны, то пользователь должен быть перенаправлен на страницу, защищенную базовой аутентификацией, без повторного запроса моих учетных данных. Кажется, это должно быть действительно просто, но я продолжаю сталкиваться с проблемами.
В настоящее время у меня есть страница, где вы вводите свои учетные данные (имя пользователя и пароль). При входе в систему выполняется POST-запрос axios к конечной точке / login, где он проверяет учетные данные для входа. Эта конечная точка возвращает код состояния 200, если учетные данные верны. Если получен ответ 200 «Успешно», я перенаправляю пользователя на страницу с базовой аутентификацией. Сервер использует промежуточное программное обеспечение Passport Express для сериализации пользователя и поддержания сеанса пользователя. Но эта информация, кажется, теряется при перенаправлении, и я не могу найти способ установить основные заголовки аутентификации на перенаправлении. Следовательно, защищенная страница, которую я перенаправил, снова запрашивает мои учетные данные. Я попытался это исправить, отправив базовые учетные данные еще раз:
window.location.replace(http://username:password@website/directory/blahblah)
но большинство современных браузеров, похоже, лишают базовых учетных данных, поэтому это не работает.
Мне удалось заставить его работать, поместив имя пользователя и пароль в URL:
window.location.replace(http://website/directory/blahblah?username=uname&password=password)
но это кажется ужасным и небезопасным способом решения того, что должно иметь простое решение, поскольку этот метод означает, что имя пользователя и пароль в конечном итоге появятся в истории моего браузера. Есть ли лучший способ реализовать такую форму входа?
Код сервера - это стандартный экспресс-сервер, использующий промежуточное программное обеспечение passport.authenticate с включенными сеансами. Что я нахожу странным, так это то, что когда мой запрос POST возвращается, req.session.passport.user содержит сериализованного пользователя, поэтому код, кажется, работает правильно, поэтому я подозреваю, что с моим кодом HTML есть проблема. Моя текущая HTML-форма для входа выглядит следующим образом:
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
</head>
<body>
<form method="get" action="javascript:loginFn()">
<input name="username" type="text" value="uname" >
<input name="password" type="password" value="pword">
<input type="submit">
</form>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
const endpoint = 'login';
const nextEndpoint = 'authorize';
//function redirect(url, method) {
// var form = document.createElement('form');
// form.method = method;
// form.action = url;
// document.body.appendChild(form);
// form.submit();
//};
async function loginFn(){
const username = document.querySelector('form [name=username]');
const password = document.querySelector('form [name=password]');
const uriParts = location.href.split('://');
const http = uriParts[0];
uriParts.splice(0, 1);
var targetUri = `${http}://${username.value}:${password.value}@${uriParts.join('://').replace(endpoint, nextEndpoint)}`;
// If credentials valid, the response code will be 200 Success
const res = await axios
.request({
baseURL: targetUri,
// Username and password used for basic auth
method: 'POST',
auth: {
username: username.value,
password: password.value,
},
params: {
login_only: true,
},
})
.catch((err) => {
// Unable to connect to the server, redirect to the NoConnection page.
if (err.message === 'Network Error') {
throw new Error('Unstable database connection');
}
if(err.request.status === 404){
throw new Error('Invalid callback URL');
}
if (err.request.status === 401) {
// Incorrect login credentials
throw new Error('Invalid login credentials');
}
});
if(res.status === 200){
// How do I NOT put the username and password in the URL redirect
window.location.replace(targetUri + '?username=uname&password=pword');
}
}
</script>
</body>
</html>