概述
使用,go+mysql实现了用户的登录,注册,和管理的简单功能,不同用户根据不同权限显示不同的内容
实战要求:
1、用户可以注册、登录;
2、登录后可以查看所有的注册的用户;
3、管理员操作对用户有删除和编辑权限。(不使用3方的web框架)
4、普通用户登录后可以查看所有用户,不能编辑、删除;
结构:
界面展示
go相关代码
db.go
package src
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"log"
)
var mdb *sql.DB
func InitDB() {
var err error
mdb, err = sql.Open("mysql", "root:5201314@tcp(127.0.0.1:3306)/user_management")//数据库连接账号密码
if err != nil {
log.Println("数据库连接失败", err)
return
} else {
log.Println("数据库连接成功")
}
}
func SelectPersonal(email string) (id int, isAdmin bool) {
log.Println("SelectPersonal")
err := mdb.QueryRow("select id,is_admin from users where username = ?", email).Scan(&id, &isAdmin)
if err != nil {
log.Println("SelectPersona", err)
}
log.Println("SelectPersonal over")
return id, isAdmin
}
func SelectAll() *sql.Rows {
log.Println("SelectAll")
stmt, err := mdb.Prepare("select * from users")
if err != nil {
log.Println("预处理失败")
}
rows, err := stmt.Query()
if err != nil {
log.Println("获取结果失败")
}
log.Println("SelectAll over")
return rows
}
func SelectPassword(email string) string {
log.Println("SelectPassword")
var storedPassword string
err := mdb.QueryRow("select password from users where username = ?", email).Scan(&storedPassword)
if err != nil {
log.Println(err)
}
log.Println("SelectPassword over")
return storedPassword
}
func AddUser(email string, password string) bool {
log.Println("AddUser")
stmt, err := mdb.Prepare("insert into users values (default,?,?,false)")
if err != nil {
fmt.Println("预处理失败")
return false
}
r, err := stmt.Exec(email, password)
if err != nil {
fmt.Println("sql执行失败")
return false
}
count, err := r.RowsAffected()
if err != nil {
fmt.Println("结果获取失败")
return false
}
if count > 0 {
log.Println("AddUser over")
fmt.Println("新增成功")
return true
} else {
fmt.Println("用户创建失败")
return false
}
}
func IsExist(email string) bool {
var emailExists bool
err := mdb.QueryRow("select exists(select 1 from users where username = ?)", email).Scan(&emailExists)
if err != nil {
log.Println(err)
}
return emailExists
}
func IsAdminEmail(email string) bool {
var emailExists bool
err := mdb.QueryRow("select is_admin from users where username = ?", email).Scan(&emailExists)
if err != nil {
log.Println(err)
}
return emailExists
}
func RemoveUser(id int) bool {
log.Println("RemoveUser")
stmt, err := mdb.Prepare("delete from users where id=?")
if err != nil {
fmt.Println("预处理失败")
return false
}
r, err := stmt.Exec(id)
if err != nil {
fmt.Println("sql执行失败")
return false
}
count, err := r.RowsAffected()
if err != nil {
fmt.Println("结果获取失败")
return false
}
if count > 0 {
log.Println("ARemoveUser over")
fmt.Println("删除成功")
return true
} else {
fmt.Println("用户删除失败")
return false
}
}
func IsAdminId(id int) bool {
var emailExists bool
err := mdb.QueryRow("select is_admin from users where id = ?", id).Scan(&emailExists)
if err != nil {
log.Println(err)
}
return emailExists
}
func Manager(id int) bool {
log.Println("Manager")
stmt, err := mdb.Prepare("update users set is_admin = ? where id=?")
if err != nil {
fmt.Println("预处理失败")
return false
}
r, err := stmt.Exec(true, id)
if err != nil {
fmt.Println("sql执行失败")
return false
}
count, err := r.RowsAffected()
if err != nil {
fmt.Println("结果获取失败")
return false
}
if count > 0 {
log.Println("Manager over")
fmt.Println("管理员设置成功")
return true
} else {
fmt.Println("管理员设置失败")
return false
}
}
func RemoveManager(id int) bool {
log.Println("RemoveManager")
if id == 1 {
return false
}
stmt, err := mdb.Prepare("update users set is_admin = ? where id=?")
if err != nil {
fmt.Println("预处理失败")
return false
}
r, err := stmt.Exec(false, id)
if err != nil {
fmt.Println("sql执行失败")
return false
}
count, err := r.RowsAffected()
if err != nil {
fmt.Println("结果获取失败")
return false
}
if count > 0 {
log.Println("RemoveManager over")
fmt.Println("管理员移除成功")
return true
} else {
fmt.Println("用户删除失败")
return false
}
}
func ChangePassword(email string, newPassword string) bool {
log.Println("ChangePassword")
stmt, err := mdb.Prepare("update users set password = ? where username=?")
if err != nil {
fmt.Println("预处理失败")
return false
}
r, err := stmt.Exec(newPassword, email)
if err != nil {
fmt.Println("sql执行失败")
return false
}
count, err := r.RowsAffected()
if err != nil {
fmt.Println("结果获取失败")
return false
}
if count > 0 {
log.Println("ChangePassword over")
fmt.Println("密码修改成功")
return true
} else {
fmt.Println("密码修改失败")
return false
}
}
main代码
package main
import (
"github.com/gorilla/mux"
"log"
"net/http"
"webTest2.0/src"
)
func main() {
src.InitDB()
r := mux.NewRouter()
r.HandleFunc("/login", src.Login).Methods("GET")
r.HandleFunc("/login/{url}", src.LoginHandler).Methods("POST")
r.HandleFunc("/index/{url}", src.IndexHandler).Methods("POST", "DELETE")
r.HandleFunc("/", src.Index).Methods("GET")
r.PathPrefix("/bootstrap5/").Handler(http.StripPrefix("/bootstrap5/", http.FileServer(http.Dir("bootstrap5"))))
log.Println("Starting server on :8090")
if err := http.ListenAndServe(":8090", r); err != nil {
log.Fatalf("Could not start server: %v", err)
}
}
index.go
package src
import (
"encoding/json"
"github.com/gorilla/mux"
"html/template"
"log"
"net/http"
"strconv"
)
type User struct {
ID int
Name string
IsAdmin bool
}
type Personal struct {
ID int
Name string
IsAdmin bool
}
type UserId struct {
UserID string `json:"userId"`
}
type Password struct {
OldPassword string
NewPassword string
}
type MyErr struct{}
func (e *MyErr) Error() string {
return "logout"
}
func Index(w http.ResponseWriter, r *http.Request) {
log.Println("index")
personal, err := CookieMessage(r)
if err != nil {
http.Redirect(w, r, "/login", http.StatusSeeOther)
return
}
rows := SelectAll()
users := make([]User, 0)
for rows.Next() {
name := ""
id := 0
var ignored interface{}
isAdmin := false
rows.Scan(&id, &name, &ignored, &isAdmin)
users = append(users, User{id, name, isAdmin})
}
tmpl, err := template.ParseFiles("view/index.html")
if err != nil {
log.Println("login.html打开失败:", err)
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}
err = tmpl.Execute(w, map[string]interface{}{
"Users": users,
"Personal": personal,
})
if err != nil {
log.Println("模板执行失败:", err)
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
}
}
func IndexHandler(w http.ResponseWriter, r *http.Request) {
log.Println("IndexHandler")
vars := mux.Vars(r)
log.Println(vars)
switch vars["url"] {
case "delete":
deleteUser(w, r)
case "updateAdmin":
addAdmin(w, r)
case "removeAdmin":
removeAdmin(w, r)
case "changePassword":
changePassword(w, r)
case "logout":
logout(w)
}
}
func CookieMessage(r *http.Request) (Personal, error) {
c, err := r.Cookie("email")
if err != nil {
// 如果获取 Cookie 失败,返回错误
return Personal{}, err
}
if c.Value == "logout" {
return Personal{}, &MyErr{}
}
id, isAdmin := SelectPersonal(c.Value)
log.Println(id, isAdmin)
personal := Personal{
id,
c.Value,
isAdmin,
}
return personal, nil
}
func changePassword(w http.ResponseWriter, r *http.Request) {
log.Println("changePassword")
response := make(map[string]string)
c, err := r.Cookie("email")
if err != nil {
response["success"] = "false"
response["message"] = "cookie获取失败"
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
return
}
var password Password
err = json.NewDecoder(r.Body).Decode(&password)
if err != nil {
response["success"] = "false"
response["message"] = "客户端信息解析错误"
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
http.Error(w, "Invalid request payload", http.StatusBadRequest)
return
}
log.Println(password.NewPassword, password.OldPassword)
if password.NewPassword == SelectPassword(c.Value) {
response["success"] = "false"
response["message"] = "新秘密与旧密码相同"
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
return
}
if password.OldPassword == SelectPassword(c.Value) {
if ChangePassword(c.Value, password.NewPassword) {
response["success"] = "true"
response["message"] = "密码修改成功"
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
return
} else {
response["success"] = "false"
response["message"] = "密码修改失败"
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
return
}
} else {
response["success"] = "false"
response["message"] = "旧密码错误"
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}
}
func deleteUser(w http.ResponseWriter, r *http.Request) {
log.Println("deleteUser")
response := make(map[string]string)
c, err := r.Cookie("email")
if err != nil {
response["success"] = "false"
response["message"] = "cookie获取失败"
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
return
}
var Id UserId
err = json.NewDecoder(r.Body).Decode(&Id)
if err != nil {
http.Error(w, "Invalid request payload", http.StatusBadRequest)
return
}
deleteId, err := strconv.Atoi(Id.UserID)
king := IsAdminId(deleteId)
id, isAdmin := SelectPersonal(c.Value)
if isAdmin {
if id == 1 {
RemoveUser(deleteId)
response["success"] = "true"
response["message"] = "删除成功"
} else if !king {
RemoveUser(deleteId)
response["success"] = "true"
response["message"] = "删除成功"
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}
log.Println("deleteUser over")
}
func addAdmin(w http.ResponseWriter, r *http.Request) {
log.Println("addAdmin")
response := make(map[string]string)
c, err := r.Cookie("email")
if err != nil {
response["success"] = "false"
response["message"] = "cookie获取失败"
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
return
}
id, _ := SelectPersonal(c.Value)
log.Println(id)
if id != 1 {
response["success"] = "false"
response["message"] = "用户权限不足"
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
return
}
var Id UserId
err = json.NewDecoder(r.Body).Decode(&Id)
log.Println(Id.UserID)
if err != nil {
log.Println(err)
http.Error(w, "Invalid request payload", http.StatusBadRequest)
return
}
updateId, err := strconv.Atoi(Id.UserID)
Manager(updateId)
response["success"] = "true"
response["message"] = "管理员设置成功"
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
log.Println("addAdmin over")
}
func removeAdmin(w http.ResponseWriter, r *http.Request) {
response := make(map[string]string)
c, err := r.Cookie("email")
if err != nil {
response["success"] = "false"
response["message"] = "cookie获取失败"
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
return
}
id, _ := SelectPersonal(c.Value)
if id != 1 {
response["success"] = "false"
response["message"] = "用户权限不足"
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
return
}
var Id UserId
err = json.NewDecoder(r.Body).Decode(&Id)
log.Println(Id.UserID)
if err != nil {
log.Println(err)
http.Error(w, "Invalid request payload", http.StatusBadRequest)
return
}
deleteId, err := strconv.Atoi(Id.UserID)
RemoveManager(deleteId)
response["success"] = "true"
response["message"] = "管理员移除成功"
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}
func logout(w http.ResponseWriter) {
log.Println("loginOut")
http.SetCookie(w, &http.Cookie{
Name: "email",
Value: "logout",
MaxAge: 5,
Path: "/",
HttpOnly: true,
SameSite: http.SameSiteLaxMode,
})
json.NewEncoder(w).Encode(map[string]interface{}{"success": true})
log.Println("loginOut over")
}
login.go
package src
import (
"encoding/json"
"fmt"
"github.com/gorilla/mux"
"html/template"
"log"
"net/http"
)
type LoginRequest struct {
Email string `json:"email"`
Password string `json:"password"`
}
func Login(w http.ResponseWriter, r *http.Request) {
_, err := CookieMessage(r)
if err == nil {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
log.Println("Login")
tmpl, err := template.ParseFiles("view/login.html")
if err != nil {
log.Println("login.html打开失败:", err)
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}
err = tmpl.Execute(w, nil)
if err != nil {
log.Println("模板执行失败:", err)
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
}
}
func LoginHandler(w http.ResponseWriter, r *http.Request) {
log.Println("LoginHandler")
vars := mux.Vars(r)
fmt.Println(vars)
log.Println("loginHandler")
switch vars["url"] {
case "login":
var req LoginRequest
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
http.Error(w, "Invalid request payload", http.StatusBadRequest)
return
}
log.Printf("Received login request: Email: %s password: %s\n", req.Email, req.Password)
emailExists := IsExist(req.Email)
if !emailExists {
response := map[string]string{"success": "false", "message": "用户不存在"}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
return
}
storedPassword := SelectPassword(req.Email)
log.Println(storedPassword)
if storedPassword != req.Password {
response := map[string]string{"success": "false", "message": "密码错误"}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
return
}
c := http.Cookie{
Name: "email",
Value: req.Email,
Path: "/",
HttpOnly: true,
Secure: true,
MaxAge: 3600,
}
http.SetCookie(w, &c)
response := map[string]string{"success": "true", "message": ""}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
case "register":
var req LoginRequest
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
http.Error(w, "Invalid request payload", http.StatusBadRequest)
return
}
log.Printf("Received login request: Email: %s password: %s\n", req.Email, req.Password)
emailExists := IsExist(req.Email)
if !emailExists {
king := AddUser(req.Email, req.Password)
response := make(map[string]string)
if king {
response["success"] = "true"
response["message"] = "注册成功"
} else {
response["success"] = "false"
response["message"] = "注册失败"
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
return
} else {
response := map[string]string{"success": "false", "message": "用户已存在"}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
return
}
default:
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
}
}
html相关代码
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户管理系统</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/mhDoLbDldZc3qpsJHpLogda//BVZbgYuw6kof4u2FrCedxOtgRZDTHgHUhOCVim" crossorigin="anonymous"></script>
<style>
.content-block {
display: none;
}
.content-block:first-of-type {
display: block;
}
</style>
</head>
<body>
<div class="container p-4">
<div class="row">
<div class="text-xxl-center list-group">
<h1>用户管理系统</h1>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-3">
<div id="list-example" class="list-group">
<a class="list-group-item list-group-item-action-active text-xxl-center list-group-item-primary" href="#list-item-1">个人</a>
<a class="list-group-item list-group-item-action text-xxl-center list-group-item-primary" href="#list-item-2">其他</a>
<a class="list-group-item list-group-item-action text-xxl-center list-group-item-primary" href="#list-item-3">设置</a>
</div>
</div>
<div class="col-9">
<div data-bs-spy="scroll" data-bs-target="#list-example" data-bs-smooth-scroll="true" class="scrollspy-example" tabindex="0">
<div id="list-item-1" class="content-block">
<table class="table">
<thead>
<tr>
<th scope="col">用户ID:</th>
<th scope="col">{{.Personal.ID}}</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">用户昵称:</th>
<td>{{.Personal.Name}}</td>
</tr>
<tr>
<th scope="row">用户身份:</th>
{{if and .Personal.IsAdmin (eq .Personal.ID 1)}}<td>超级管理员</td>
{{else if .Personal.IsAdmin}}<td>管理员</td>
{{else}}<td>普通成员</td>
{{end}}
</tr>
</tbody>
</table>
</div>
<div id="list-item-2" class="content-block">
<table class="table">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">用户</th>
<th scope="col">身份</th>
{{if and .Personal.IsAdmin (eq .Personal.ID 1)}}
<th scope="col">管理</th>
{{end}}
{{if .Personal.IsAdmin}}
<th scope="col">删除</th>
{{end}}
</tr>
</thead>
<tbody>
{{range .Users}}
<tr>
<th scope="row">{{.ID}}</th>
<td>{{.Name}}</td>
{{if and .IsAdmin (eq .ID 1)}}<td>超级管理员</td>
{{else if .IsAdmin}}<td>管理员</td>
{{else}}<td>普通用户</td>
{{end}}
{{if eq $.Personal.ID 1}}
{{if eq .ID 1}}
{{else if .IsAdmin}}
<td><button type="button" class="btn btn-primary remove-user-btn" data-id="{{.ID}}">移除管理员</button></td>
<td><button type="button" class="btn btn-danger delete-user-btn" data-id="{{.ID}}">删除</button></td>
{{else}}
<td><button type="button" class="btn btn-primary manage-user-btn" data-id="{{.ID}}">设置管理员</button></td>
<td><button type="button" class="btn btn-danger delete-user-btn" data-id="{{.ID}}">删除</button></td>
{{end}}
{{else if $.Personal.IsAdmin}}
{{if not .IsAdmin}}
<td><button type="button" class="btn btn-danger delete-user-btn" data-id="{{.ID}}">删除</button></td>
{{end}}
{{end}}
</tr>
{{end}}
</tbody>
</table>
</div>
<div id="list-item-3" class="content-block">
<div class="container">
<div class="row">
<div class="text-xxl-center col-6">
<button type="button" class="btn btn-primary" id="change-password-btn">修改密码</button>
</div>
<div class="col-6">
<button type="button" class="btn btn-primary" id="logout-btn">退出登录</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="changePasswordModal" tabindex="-1" aria-labelledby="changePasswordModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="changePasswordModalLabel">修改密码</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form id="change-password-form">
<div class="mb-3">
<label for="old-password" class="form-label">旧密码</label>
<input type="password" class="form-control" id="old-password" required>
</div>
<div class="mb-3">
<label for="new-password" class="form-label">新密码</label>
<input type="password" class="form-control" id="new-password" required>
</div>
<div class="mb-3">
<label for="confirm-password" class="form-label">确认新密码</label>
<input type="password" class="form-control" id="confirm-password" required>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" id="submit-change-password">确定</button>
</div>
</div>
</div>
</div>
<script>
document.querySelectorAll('#list-example a').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const targetId = this.getAttribute('href');
document.querySelectorAll('.content-block').forEach(block => {
block.style.display = 'none';
});
document.querySelector(targetId).style.display = 'block';
});
});
// 管理用户
document.querySelectorAll('.manage-user-btn').forEach(button => {
button.addEventListener('click', function() {
const userId = this.getAttribute('data-id');
if (confirm('确定要设置当前用户为管理员吗?')) {
fetch(`/index/updateAdmin`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ "userId":userId })
}).then(response => response.json())
.then(data => {
if (data.success === "true") {
alert('用户已成功设置成管理员!');
location.reload();
} else {
alert('设置管理员失败:' + data.message);
}
});
}
});
});
document.querySelectorAll('.remove-user-btn').forEach(button => {
button.addEventListener('click', function() {
const userId = this.getAttribute('data-id');
if (confirm('确定要取消当前用户管理员身份吗?')) {
fetch(`/index/removeAdmin`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ "userId":userId })
}).then(response => response.json())
.then(data => {
if (data.success === "true") {
alert('已成功取消当前用户管理员身份!');
location.reload();
} else {
alert('取消当前用户管理员身份失败:' + data.message);
}
});
}
});
});
// 删除用户
document.querySelectorAll('.delete-user-btn').forEach(button => {
button.addEventListener('click', function() {
const userId = this.getAttribute('data-id');
if (confirm('确定要删除该用户吗?')) {
fetch(`/index/delete`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ "userId":userId }),
}).then(response => response.json())
.then(data => {
if (data.success === "true") {
alert('用户已成功删除!');
location.reload();
} else {
alert('删除用户失败:' + data.message);
}
});
}
});
});
document.getElementById('logout-btn').addEventListener('click', function() {
fetch('/index/logout', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
credentials: 'include'
}).then(response => response.json())
.then(data => {
if (data.success) {
alert('注销成功');
window.location.href="/";
} else {
alert('注销失败:' + data.message);
}
});
});
document.addEventListener('DOMContentLoaded', function() {
const changePasswordModal = new bootstrap.Modal(document.getElementById('changePasswordModal'));
document.getElementById('change-password-btn').addEventListener('click', function () {
changePasswordModal.show();
});
document.getElementById('submit-change-password').addEventListener('click', function () {
const oldPassword = document.getElementById('old-password').value;
const newPassword = document.getElementById('new-password').value;
const confirmPassword = document.getElementById('confirm-password').value;
if (newPassword !== confirmPassword) {
alert('新密码和确认密码不一致!');
return;
}
fetch('/index/changePassword', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
"oldPassword": oldPassword,
"newPassword": newPassword
})
}).then(response => response.json())
.then(data => {
if (data.success === "true") {
alert('密码已成功更改!');
changePasswordModal.hide();
} else {
if (data.message === "新秘密与旧密码相同"){
alert('新秘密与旧密码相同');
}
alert('更改密码失败:' + data.message);
}
});
});
});
</script>
</body>
</html>
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/mhDoLbDldZc3qpsJHpLogda//BVZbgYuw6kof4u2FrCedxOtgRZDTHgHUhOCVim" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<form id="loginForm" onsubmit="return handleSubmit(event, 'login')">
<div class="col-4 mx-auto">
<div class="col-md-4 mx-auto p-6">
<h2>登录/注册</h2>
</div>
</div>
<div class="col-4 mx-auto">
<label for="exampleInputEmail1" class="form-label">邮箱地址</label>
<input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp">
</div>
<div class="col-4 mx-auto">
<label for="exampleInputPassword1" class="form-label">密码</label>
<input type="password" class="form-control" id="exampleInputPassword1">
</div>
<div class="col-4 mx-auto">
<button type="submit" class="col-12 btn-outline-primary p-2">登录</button>
</div>
<div class="col-4 mx-auto">
<button type="button" class="col-12 btn-outline-primary p-2" onclick="handleSubmit(event, 'register')">注册</button>
</div>
</form>
</div>
<script>
function handleSubmit(event, action) {
event.preventDefault();
const email = document.getElementById('exampleInputEmail1').value;
const password = document.getElementById('exampleInputPassword1').value;
const url = action === 'login' ? '/login/login' : '/login/register';
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ email, password }),
})
.then(response => response.json())
.then(data => {
if (data.success === "true") {
if (action === 'login') {
alert('登录成功!');
window.location.href = '/';
} else if (action === 'register') {
alert('注册成功,请登录!');
}
} else {
if (data.message === "用户不存在") {
alert('用户不存在,请先注册');
} else if (data.message === "密码错误") {
alert('密码错误,请重新输入');
} else if (data.message === "用户已存在") {
alert('用户已存在,请直接登录');
} else {
alert('请求失败,请稍后再试');
}
}
})
.catch((error) => {
console.error('Error:', error);
alert('请求错误,请稍后再试');
});
}
</script>
</body>
</html>