头图

Email Verification Power By Gin(speed)

源代码

🏀🏀
Email Verification Power By Gin
🏀🏀

bilibili 在线吹水

⚽️⚽️
利用gin实现新用户的注册登录与邮箱激活
⚽️⚽️

Features

  • 🐰 数据持久化 MongoDB
  • 🦊 验证码缓存 Redis
  • 🐼 邮件发送 SMTP
  • 🐮 邮件模板 HTML
  • 🐦 接口文档 Swagger

SNAPSHOTS

Swagger

有些前端不喜欢在电脑上装客户端,swagger会成为他的好盆友

type PingResponse struct {
    CommonResponse
    Msg string `json:"Message" example:"pong"`
}

// Ping godoc
// @Summary Test if server is alive
// @Schemes
// @Tags Common
// @Produce json
// @Success 200 {object}  models.PingResponse
// @Router /ping [get]
func Ping(c *gin.Context) {
    c.JSON(200, gin.H{
        "message": "pong",
    })
}

jwt

其实jwt服务端做很麻烦,但是客户端调用简单。

可谓一门舍己为人的技术

注意一下几点:

  • 除签发时间到期外,没有其他办法让已经生成的JWT失效,除非服务器端换算法。
  • JWT不应该存储敏感的信息
  • 如果一意孤行的存放敏感信息,请再次加密。
  • 最好设置较短的过期时间,防止被盗用后一直有效,降低损失。
  • Payload也可以存储一些业务信息,以便减少数据库的压力。
func InitAuthMiddlewares(controllers controllers.UserControllers) (*jwt.GinJWTMiddleware, error) {
    return jwt.New(&jwt.GinJWTMiddleware{
        IdentityKey:      "id",
        Realm:            "email-verification",
        SigningAlgorithm: "HS256",
        Key:              []byte(config.GetConfig().JwtKey),
        Timeout:          time.Hour * time.Duration(config.GetConfig().JwtAccessAge),
        MaxRefresh:       time.Hour * time.Duration(config.GetConfig().JwtRefreshAge),
        TokenLookup:      "header: Authorization, query: token, cookie: jwt",
        TokenHeadName:    "Bearer",
        TimeFunc:         time.Now,
        Authenticator:    controllers.Login,
        Authorizator:     authorizedFunc,
        PayloadFunc:      payloadHandle,
        LoginResponse:    loginResponse,
        Unauthorized:     unauthorizedFunc,
        IdentityHandler:  identityHandler,
    })
}

...

authMiddleware, err := middles.InitAuthMiddlewares(controllersImpl)
if err != nil { panic(err) }
router.POST("/login", authMiddleware.LoginHandler)
router.GET("/refresh_token", authMiddleware.RefreshHandler)
router.GET("/logout", authMiddleware.LogoutHandler)
router.GET("/user", authMiddleware.MiddlewareFunc(), controllersImpl.Info)

requestID

  • 如何将客户端请求与服务端日志关联
  • 微服务架构下,访问日志如何查询
  • 不同项目交互出现异常,如何做日志关联

答案:requestID

r := gin.New()
r.Use(requestid.New())

r.GET("/ping", func(c *gin.Context) {
   c.String(http.StatusOK, "pong "+fmt.Sprint(time.Now().Unix()))
})

r.Run(":8080")

Email-template

golang自带的html/template模板,可以很方便的实现邮件模板

写邮件html和浏览器不一样,你永远也想象不到收件人的客户端可以理解html到什么程度。

注意两点吧

  1. 很多邮件客户端对html的全局style支持不太好,所以需要使用premailer将style转换为内联样式。
  2. 大部分人都有手机看邮件的习惯,邮件的layout一定要可响应式的。
template.ExecuteTemplate(&body, "email-verify.html", &data)
htmlString := body.String()
prem, _ := premailer.NewPremailerFromString(htmlString, nil)
htmlInline, err := prem.Transform()
m := gomail.NewMessage()

m.SetHeader("From", from)
m.SetHeader("To", to)
m.SetHeader("Subject", data.Subject)
m.SetBody("text/html", htmlInline)
m.AddAlternative("text/plain", html2text.HTML2Text(body.String()))

d := gomail.NewDialer(smtpHost, smtpPort, smtpUser, smtpPass)
d.TLSConfig = &tls.Config{InsecureSkipVerify: true}

相关阅读

Swagger

Golang and MongoDB using the official mongo-driver

Gin middleware with Swagger 2.0

使用swag自动生成Restful API文档

JWT

Issue:jwt in swagger not include Bearer

如何在Gin框架中使用JWT实现认证机制

JWT Middleware for Gin Framework

gin-jwt-example

Request ID middleware for Gin Framework

Email

在线预览和内联email-html-style

在线编辑email-html

响应式邮件模板


小叉Ray
0 声望1 粉丝

Rust~Golang~TypeScript~数量取胜的编程捣鼓法~