|
@@ -0,0 +1,110 @@
|
|
|
|
|
+package main
|
|
|
|
|
+
|
|
|
|
|
+import (
|
|
|
|
|
+ "encoding/json"
|
|
|
|
|
+ "io/fs"
|
|
|
|
|
+ "net/http"
|
|
|
|
|
+ "strings"
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+type LoginReq struct {
|
|
|
|
|
+ Username string `json:"username"`
|
|
|
|
|
+ Password string `json:"password"`
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+type LoginResp struct {
|
|
|
|
|
+ Success bool `json:"success"`
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func loginHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
+ if r.Method != http.MethodPost {
|
|
|
|
|
+ w.WriteHeader(http.StatusMethodNotAllowed)
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ var req LoginReq
|
|
|
|
|
+ if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
|
|
|
|
+ w.WriteHeader(http.StatusBadRequest)
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ok := req.Username == "admin" && req.Password == "admin123456"
|
|
|
|
|
+
|
|
|
|
|
+ if ok {
|
|
|
|
|
+ sessionID := createSession()
|
|
|
|
|
+ addSession(sessionID)
|
|
|
|
|
+
|
|
|
|
|
+ http.SetCookie(w, &http.Cookie{
|
|
|
|
|
+ Name: "session_id",
|
|
|
|
|
+ Value: sessionID,
|
|
|
|
|
+ Path: "/",
|
|
|
|
|
+ HttpOnly: true,
|
|
|
|
|
+ SameSite: http.SameSiteStrictMode,
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ w.Header().Set("Content-Type", "application/json")
|
|
|
|
|
+ json.NewEncoder(w).Encode(LoginResp{Success: ok})
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func logoutHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
+ if cookie, err := r.Cookie("session_id"); err == nil {
|
|
|
|
|
+ sessionMu.Lock()
|
|
|
|
|
+ delete(sessions, cookie.Value)
|
|
|
|
|
+ sessionMu.Unlock()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ http.SetCookie(w, &http.Cookie{
|
|
|
|
|
+ Name: "session_id",
|
|
|
|
|
+ Value: "",
|
|
|
|
|
+ Path: "/",
|
|
|
|
|
+ MaxAge: -1,
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ http.Redirect(w, r, "/", http.StatusFound)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (ui *WebUI) rootHandler(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
+ path := r.URL.Path
|
|
|
|
|
+
|
|
|
|
|
+ w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
|
|
|
|
+ w.Header().Set("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0")
|
|
|
|
|
+ w.Header().Set("Pragma", "no-cache")
|
|
|
|
|
+ w.Header().Set("Expires", "0")
|
|
|
|
|
+
|
|
|
|
|
+ // 1, 未登录时, 只能看登录页
|
|
|
|
|
+ if !checkSession(r) {
|
|
|
|
|
+ data, err := fs.ReadFile(ui.fs, "login.html")
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ http.NotFound(w, r)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ w.Write(data)
|
|
|
|
|
+ }
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 2, 登录成功, 展示导航首页
|
|
|
|
|
+ if path == "/" {
|
|
|
|
|
+ data, err := fs.ReadFile(ui.fs, "index.html")
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ http.NotFound(w, r)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ w.Write(data)
|
|
|
|
|
+ }
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 3, 在网站内跳转其它功能页
|
|
|
|
|
+ if strings.HasPrefix(path, "/pages/") { // path 形如 "/pages/page1.html"
|
|
|
|
|
+ data, err := fs.ReadFile(ui.fs, path[1:])
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ http.NotFound(w, r)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ w.Write(data)
|
|
|
|
|
+ }
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 4, 访问其它不认识的页面时
|
|
|
|
|
+ http.NotFound(w, r)
|
|
|
|
|
+}
|