是否有可能注销用户从一个网站,如果他是使用基本身份验证?
杀死会话是不够的,因为一旦用户通过身份验证,每个请求都包含登录信息,因此用户下次使用相同的凭据访问站点时将自动登录。
目前唯一的解决方案是关闭浏览器,但从可用性的角度来看,这是不可接受的。
是否有可能注销用户从一个网站,如果他是使用基本身份验证?
杀死会话是不够的,因为一旦用户通过身份验证,每个请求都包含登录信息,因此用户下次使用相同的凭据访问站点时将自动登录。
目前唯一的解决方案是关闭浏览器,但从可用性的角度来看,这是不可接受的。
当前回答
正如其他人所说,我们需要获得相同的URL并发送一个错误(例如401:StatusUnauthorized之类的),仅此而已。
我使用Get方法让它知道我需要登出,
下面是一个使用golang进行写作的完整示例。
package main
import (
"crypto/subtle"
"fmt"
"log"
"net/http"
)
func BasicAuth(username, password, realm string, handlerFunc http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
queryMap := r.URL.Query()
if _, ok := queryMap["logout"]; ok { // localhost:8080/public/?logout
w.WriteHeader(http.StatusUnauthorized) // 401
_, _ = w.Write([]byte("Success logout!\n"))
return
}
user, pass, ok := r.BasicAuth()
if !ok ||
subtle.ConstantTimeCompare([]byte(user), []byte(username)) != 1 ||
subtle.ConstantTimeCompare([]byte(pass), []byte(password)) != 1 {
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/WWW-Authenticate
w.Header().Set("WWW-Authenticate", `Basic realm="`+realm+`", charset="UTF-8"`)
w.WriteHeader(http.StatusUnauthorized)
_, _ = w.Write([]byte("Unauthorised.\n"))
return
}
handlerFunc(w, r)
}
}
type UserInfo struct {
name string
psw string
}
func main() {
portNumber := "8080"
guest := UserInfo{"guest", "123"}
// localhost:8080/public/ -> ./public/everyone
publicHandler := http.StripPrefix(
"/public/", http.FileServer(http.Dir("./public/everyone")),
)
publicHandlerFunc := func(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
publicHandler.ServeHTTP(w, r)
/*
case http.MethodPost:
case http.MethodPut:
case http.MethodDelete:
*/
default:
return
}
}
http.HandleFunc("/public/",
BasicAuth(guest.name, guest.psw, "Please enter your username and password for this site",
publicHandlerFunc),
)
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", portNumber), nil))
}
当您已经登出时,您需要刷新(F5)页面。否则,您可能会看到旧内容。
其他回答
对于使用Windows身份验证(也称为协商、Kerberos或NTLM身份验证)的任何人,我使用ASP。NET Core和Angular。
我找到了一种有效的方式来改变用户!
我修改我的登录方法在javascript方面,就像这样:
protected login(changeUser: boolean = false): Observable<AuthInfo> {
let params = new HttpParams();
if(changeUser) {
let dateNow = this.datePipe.transform(new Date(), 'yyyy-MM-dd HH:mm:ss');
params = params.set('changeUser', dateNow!);
}
const url: string = `${environment.yourAppsApiUrl}/Auth/login`;
return this.http.get<AuthInfo>(url, { params: params });
}
下面是我在后台的方法:
[Route("api/[controller]")]
[ApiController]
[Produces("application/json")]
[Authorize(AuthenticationSchemes = NegotiateDefaults.AuthenticationScheme)]
public class AuthController : Controller
{
[HttpGet("login")]
public async Task<IActionResult> Login(DateTime? changeUser = null)
{
if (changeUser > DateTime.Now.AddSeconds(-3))
return Unauthorized();
...
... (login process)
...
return Ok(await _authService.GetToken());
}
}
return Unauthorized()返回401代码,导致浏览器识别弹出窗口出现,以下是过程:
如果我想更改用户,我现在将日期作为参数传输。 如果从那一刻起不超过3秒,我就返回401代码。 我完成了我的凭证,并将具有相同参数的相同请求发送到后端。 由于已经过去了3秒多,我继续登录过程,但这次使用的是新的凭据!
所有你需要的是重定向用户注销URL和返回401未经授权的错误。在错误页面(必须在没有基本身份验证的情况下访问)上,您需要提供到主页的完整链接(包括方案和主机名)。用户将点击此链接,浏览器将再次要求凭据。
Nginx的示例:
location /logout {
return 401;
}
error_page 401 /errors/401.html;
location /errors {
auth_basic off;
ssi on;
ssi_types text/html;
alias /home/user/errors;
}
错误页面/home/user/errors/401.html:
<!DOCTYPE html>
<p>You're not authorised. <a href="<!--# echo var="scheme" -->://<!--# echo var="host" -->/">Login</a>.</p>
这是我的注销是如何使用形式工作:
创建基本认证用户注销密码注销 创建目录logout/和添加.htaccess:行'要求用户注销'
RewriteEngine On
AuthType Basic
AuthName "Login"
AuthUserFile /mypath/.htpasswd
require user logout
添加注销按钮,网站的形式如下:
<form action="https://logout:logout@example.com/logout/" method="post">
<button type="submit">Logout</button>
</form>
Logout /index.php可以是这样的:
<?php
echo "LOGOUT SUCCESS";
header( "refresh:2; url=https://example.com" );
?>
5.9.2022确认支持chrome、edge和三星android网络浏览器
bobince对这个问题的补充回答是…
使用Ajax,您可以将“注销”链接/按钮连接到Javascript函数。让这个函数发送带有错误用户名和密码的XMLHttpRequest。这应该会得到401。然后设置文档。位置返回到预登录页面。这样,用户将永远不会在注销期间看到额外的登录对话框,也不必记得输入错误的凭据。
我刚刚在Chrome(79)、Firefox(71)和Edge(44)上测试了以下程序,效果良好。它应用上面提到的脚本解决方案。
只需添加一个“注销”链接,点击返回以下html
<div>You have been logged out. Redirecting to home...</div>
<script>
var XHR = new XMLHttpRequest();
XHR.open("GET", "/Home/MyProtectedPage", true, "no user", "no password");
XHR.send();
setTimeout(function () {
window.location.href = "/";
}, 3000);
</script>