Go语言服务端应用骨架实现方案
Go语言服务端应用骨架实现方案 我的新项目面向所有想要编写HTML5网络应用程序的开发者。
geosoft1/ssas
Go语言的服务器端应用程序骨架。通过在GitHub上创建账户来为geosoft1/ssas开发做出贡献。
基础服务器端网络应用程序具有以下功能:
- HTTP/HTTPS服务器
- 中间件上的路由和认证(使用gorilla mux)
- 会话管理(使用gorilla sessions)
- 用户管理(注册、修改和删除用户、通过邮件恢复密码)
- 网络故障时的离线回退页面
- 模块化设计,易于扩展
- JSON格式的配置文件
- 从文件或模型生成数据库(使用MySQL Workbench)
- 支持移动访问的响应式界面,禁用浏览器后退按钮
关于这个项目的DEV.to文章在这里。
尽情使用。
太棒的想法!
根据您实际需要的模板代码量,融入一些最佳实践可能会很有用,例如在注册时使用类似 bcrypt 的库来实现开箱即用的密码加盐和哈希处理。
我同意这个观点,这东西居然用明文存储未经哈希和加盐处理的密码。我也希望能有更好的配置格式。
说实话,我不太喜欢它:功能太少而且做得也不好。不过我觉得作为博客文章里的示例应用还行,所以可能只是个"宣传"手段而已。
并非要批评,但我确实想质疑这样一种假设:仅仅因为应用程序是"内部"的,我们就可以绕过一些基本的安全要求(如盐值、哈希、强健的身份验证等)。
物理边界固然重要,但可以被绕过,而且这种情况经常发生。心怀不满的员工是任何公司面临的最大风险之一,他们就在这个边界之内。此外,一些"内部"应用程序可能会被员工在可疑网络环境下从外部设施访问。VPN 会有所帮助,但无人看管的未锁定笔记本电脑仍然是个问题。在我看来,无论部署点在哪里,安全基础都是必不可少的。培训有助于预防某些风险,精心设计的软件也是如此。
欢迎提出不同意见,再次强调我并非要批评您的工作。我当然无法做得更好,而且无论如何我都不是该领域的专家或专业人士。我只是一个学生,努力提升自己的知识和技能。感谢您的贡献,希望您也能继续进步!
geosoft1: 没有广告,正如您所见许可证是GPL。我只是觉得这个基础程序很有用,所以分享了可能对他人有帮助的想法和代码,就像它曾帮助过我一样。
您误会了。我并不是指您通过这个程序进行自我宣传。
我的意思是,虽然我不喜欢把它作为鼓励人们使用的方案(基于我初次接触时的感受,或者说它被"宣传"给我的方式),但对于展示如何使用Go快速构建Web应用程序基础的博客文章来说,这或许还算合适。
关于"功能太少",再次说明,我并非批评其功能数量,而是强调如果它只实现少量功能(这完全没问题),就应该把这些功能做完善(比如使用明文密码就是不合适的,即便是企业内部应用也是如此)。
文字交流容易丢失语气信息,我无法判断我的意见是否让您感到不快,但希望这些观点无论如何能带来一些帮助。
如果我的理解正确,到目前为止提出的主要问题是密码以明文(未哈希)形式存储在数据库中。我同意这一点可以解决,可能会在下一个版本中实现。
对于内部应用程序以及其他情况,事情实际上并没有那么糟糕。在VPN和一些常规安全解决方案的保护下,不同公司的员工访问他们的内部资源(如共享文件或其他内容),因此在这种情况下,黑客攻击Linux机器以查看数据库中的某些密码并不是一件简单的事情。出于这个原因,我目前没有过分强调安全性,而是更注重功能性,随后再解决这些安全问题。
无论如何,HTTPS仍然可以通过证书使用,所以在有人入侵你的数据库之前,我认为使用这个并没有太大危险。但我愿意接受建设性的建议来改进这个想法。
看,我本不打算回应,但试图为此辩解只会让情况更糟。数据库是用户抵御恶意攻击的最后防线,因此以明文存储密码就是错误的,没有任何借口。"情况没那么糟"或"我觉得这样用风险不大"之类的说辞实在天真、危险且错误。
这可能是主要问题,但并非唯一问题。例如,在您的主函数中看到这个引起了我的注意:
// 注意:这将避免处理器过载
runtime.GOMAXPROCS(1)
您认为强制用户接受这样的设置合理吗?您对他们的机器了解多少,竟要硬编码这样的限制?
您的主文件还包含User、Database和SMTP结构体,而"添加简单应用"部分并未提及该应用的模型或结构体,这很可能意味着您期望用户在主文件中创建数据、配置和其他结构体:这完全违背了模块化设计的理念。
请不要误解,我并非要攻击您或您的代码,只是指出您选择公开的这个包存在的一些问题。如我之前所说,作为博客速成示例这基本可以接受,但请勿在明显未达标时声称"项目已可投入运行"。
以下是针对 Go 语言服务端应用骨架实现方案的专业回答,基于你提供的项目描述和功能需求:
实现方案概述
你的项目 ssas 提供了一个基于 Go 语言的服务器端应用骨架,适用于构建 HTML5 网络应用程序。它集成了 HTTP/HTTPS 服务器、路由、会话管理、用户管理等功能,采用模块化设计,便于扩展。以下是一个示例实现,展示如何构建一个基础服务器骨架,涵盖你提到的关键功能。
示例代码:基础服务器骨架
这个示例使用 gorilla/mux 处理路由和中间件,gorilla/sessions 管理会话,并模拟用户注册和认证流程。假设使用 JSON 配置文件(如 config.json)来设置服务器参数。
-
项目结构和配置文件 创建一个
config.json文件来存储服务器配置:{ "server": { "host": "localhost", "port": 8080, "use_https": false }, "database": { "driver": "mysql", "dsn": "user:password@tcp(localhost:3306)/appdb" }, "session": { "secret_key": "your-secret-key" } } -
主文件 (main.go) 初始化服务器、加载配置、设置路由和中间件:
package main import ( "encoding/json" "log" "net/http" "os" "github.com/gorilla/mux" "github.com/gorilla/sessions" ) // Config 结构体定义配置文件格式 type Config struct { Server struct { Host string `json:"host"` Port int `json:"port"` UseHTTPS bool `json:"use_https"` } `json:"server"` Session struct { SecretKey string `json:"secret_key"` } `json:"session"` } var store = sessions.NewCookieStore([]byte("your-secret-key")) // 从配置中加载 func main() { // 加载配置文件 config := loadConfig("config.json") store = sessions.NewCookieStore([]byte(config.Session.SecretKey)) // 初始化路由器 r := mux.NewRouter() // 添加中间件:例如日志记录 r.Use(loggingMiddleware) // 设置路由 r.HandleFunc("/", homeHandler).Methods("GET") r.HandleFunc("/register", registerHandler).Methods("POST") r.HandleFunc("/login", loginHandler).Methods("POST") r.HandleFunc("/logout", logoutHandler).Methods("POST") // 启动 HTTP/HTTPS 服务器 addr := fmt.Sprintf("%s:%d", config.Server.Host, config.Server.Port) if config.Server.UseHTTPS { log.Printf("Starting HTTPS server on %s", addr) log.Fatal(http.ListenAndServeTLS(addr, "cert.pem", "key.pem", r)) } else { log.Printf("Starting HTTP server on %s", addr) log.Fatal(http.ListenAndServe(addr, r)) } } func loadConfig(filename string) Config { file, err := os.Open(filename) if err != nil { log.Fatal("Failed to load config:", err) } defer file.Close() var config Config decoder := json.NewDecoder(file) err = decoder.Decode(&config) if err != nil { log.Fatal("Failed to decode config:", err) } return config } func loggingMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { log.Printf("%s %s", r.Method, r.URL.Path) next.ServeHTTP(w, r) }) } func homeHandler(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Welcome to the Go server skeleton!")) } func registerHandler(w http.ResponseWriter, r *http.Request) { // 示例:处理用户注册(实际中应验证输入并存储到数据库) email := r.FormValue("email") password := r.FormValue("password") log.Printf("Registering user: %s", email) w.Write([]byte("User registered successfully")) } func loginHandler(w http.ResponseWriter, r *http.Request) { session, _ := store.Get(r, "user-session") // 示例认证逻辑(实际中应检查数据库) session.Values["authenticated"] = true session.Save(r, w) w.Write([]byte("Logged in successfully")) } func logoutHandler(w http.ResponseWriter, r *http.Request) { session, _ := store.Get(r, "user-session") session.Values["authenticated"] = false session.Save(r, w) w.Write([]byte("Logged out successfully")) } -
用户管理和会话处理 使用
gorilla/sessions管理用户会话。在实际应用中,你需要集成数据库(如 MySQL)来存储用户数据,并实现密码恢复等功能。以下是一个扩展示例,添加用户模型和数据库操作(使用database/sql和 MySQL 驱动):import ( "database/sql" _ "github.com/go-sql-driver/mysql" ) // User 结构体定义用户模型 type User struct { ID int Email string Password string // 实际中应使用哈希存储 } func initDB(dsn string) *sql.DB { db, err := sql.Open("mysql", dsn) if err != nil { log.Fatal("Failed to connect to database:", err) } return db } // 在 registerHandler 中保存用户到数据库 func registerHandler(w http.ResponseWriter, r *http.Request) { email := r.FormValue("email") password := r.FormValue("password") // 实际中应使用 bcrypt 等哈希 db := initDB("user:password@tcp(localhost:3306)/appdb") defer db.Close() _, err := db.Exec("INSERT INTO users (email, password) VALUES (?, ?)", email, password) if err != nil { http.Error(w, "Registration failed", http.StatusInternalServerError) return } w.Write([]byte("User registered successfully")) } -
离线回退和响应式界面 对于离线回退,你可以添加一个服务工作者(Service Worker)来缓存资源,但这是在客户端实现的。在服务器端,确保路由处理静态文件(如 HTML、CSS、JS)。使用
http.FileServer提供静态文件:r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("./static"))))
总结
这个示例展示了如何用 Go 语言构建一个服务器端应用骨架,覆盖了 HTTP/HTTPS 服务器、路由、中间件、会话管理和基础用户功能。通过模块化设计,你可以轻松扩展其他功能,如数据库集成或移动优化界面。根据你的项目需求,进一步集成 MySQL Workbench 生成的模型或添加认证中间件来增强安全性。


