是否有可能注销用户从一个网站,如果他是使用基本身份验证?
杀死会话是不够的,因为一旦用户通过身份验证,每个请求都包含登录信息,因此用户下次使用相同的凭据访问站点时将自动登录。
目前唯一的解决方案是关闭浏览器,但从可用性的角度来看,这是不可接受的。
是否有可能注销用户从一个网站,如果他是使用基本身份验证?
杀死会话是不够的,因为一旦用户通过身份验证,每个请求都包含登录信息,因此用户下次使用相同的凭据访问站点时将自动登录。
目前唯一的解决方案是关闭浏览器,但从可用性的角度来看,这是不可接受的。
当前回答
添加到你的应用程序:
@app.route('/logout')
def logout():
return ('Logout', 401, {'WWW-Authenticate': 'Basic realm="Login required"'})
其他回答
在地址栏中输入chrome://restart, chrome和所有在后台运行的应用程序将重新启动,Auth密码缓存将被清除。
添加到你的应用程序:
@app.route('/logout')
def logout():
return ('Logout', 401, {'WWW-Authenticate': 'Basic realm="Login required"'})
正如其他人所说,我们需要获得相同的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响应头叫做Clear-Site-Data。如果你的服务器回复包含一个Clear-Site-Data: "cookies"头,那么身份验证凭证(不仅仅是cookies)应该被删除。我在Chrome 77上测试了它,但控制台显示了这个警告:
Clear-Site-Data header on 'https://localhost:9443/clear': Cleared data types:
"cookies". Clearing channel IDs and HTTP authentication cache is currently not
supported, as it breaks active network connections.
并且认证凭证没有被删除,所以这不能(目前)实现基本的认证注销,但也许将来会。没有在其他浏览器上测试。
引用:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Clear-Site-Data
https://www.w3.org/TR/clear-site-data/
https://github.com/w3c/webappsec-clear-site-data
https://caniuse.com/#feat=mdn-http_headers_clear-site-data_cookies
所有你需要的是重定向用户注销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>