是否有可能注销用户从一个网站,如果他是使用基本身份验证?
杀死会话是不够的,因为一旦用户通过身份验证,每个请求都包含登录信息,因此用户下次使用相同的凭据访问站点时将自动登录。
目前唯一的解决方案是关闭浏览器,但从可用性的角度来看,这是不可接受的。
是否有可能注销用户从一个网站,如果他是使用基本身份验证?
杀死会话是不够的,因为一旦用户通过身份验证,每个请求都包含登录信息,因此用户下次使用相同的凭据访问站点时将自动登录。
目前唯一的解决方案是关闭浏览器,但从可用性的角度来看,这是不可接受的。
当前回答
下面是一个使用jQuery的非常简单的Javascript示例:
function logout(to_url) {
var out = window.location.href.replace(/:\/\//, '://log:out@');
jQuery.get(out).error(function() {
window.location = to_url;
});
}
此登录用户退出而不再次显示浏览器登录框,然后将其重定向到注销页面
其他回答
使用会话ID (cookie) 使服务器上的会话ID失效 不接受会话id无效的用户
正如其他人所说,我们需要获得相同的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)页面。否则,您可能会看到旧内容。
其实很简单。
只需在浏览器中访问以下内容,并使用错误的凭据: http://username:password@yourdomain.com
这应该会“让你退出”。
发送https://invalid_login@hostname在任何地方都可以工作,除了Mac上的Safari(好吧,没有勾选Edge,但也应该工作)。
当用户在HTTP基本身份验证弹出框中选择“记住密码”时,Safari中的注销不工作。在这种情况下,密码存储在Keychain Access (Finder > Applications > Utilities > Keychain Access(或CMD+SPACE并键入“Keychain Access”))中。发送https://invalid_login@hostname不会影响钥匙链访问,所以这个复选框不可能在Mac上的Safari上注销。至少它是如何为我工作的。
MacOS Mojave (10.14.6), Safari 12.1.2。
下面的代码在Firefox(73)、Chrome(80)和Safari(12)中运行良好。当用户导航到登出页面时,执行代码并删除凭据。
//It should return 401, necessary for Safari only
const logoutUrl = 'https://example.com/logout';
const xmlHttp = new XMLHttpRequest();
xmlHttp.open('POST', logoutUrl, true, 'logout');
xmlHttp.send();
此外,由于某些原因,Safari不会在HTTP基本身份验证弹出框中保存凭据,即使选择了“记住密码”。其他浏览器可以正确地做到这一点。
我刚刚在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>