企业查询网站企查查,网站 默认首页,百度帐号登录,oa系统公司排名本篇介绍HTTP Basic Auth的实现以及Recovery机制。 HTTP Basic Auth Basic Auth是一种开放平台认证方式#xff0c;简单的说就是需要你输入用户名和密码才能继续访问。对于Basic Auth的概念不过多的进行介绍#xff0c;直接进入如何实现的过程。 Basic Auth说白了就是账号和密…本篇介绍HTTP Basic Auth的实现以及Recovery机制。 HTTP Basic Auth Basic Auth是一种开放平台认证方式简单的说就是需要你输入用户名和密码才能继续访问。对于Basic Auth的概念不过多的进行介绍直接进入如何实现的过程。 Basic Auth说白了就是账号和密码的组合所以定义用来存储账号和密码的结构体。 type (// BasicAuthPair .BasicAuthPair struct {Code stringUser string}// Account .Account struct {User stringPassword string}// Accounts .Accounts []Account// Pairs .Pairs []BasicAuthPair
)
复制代码其中 Accounts 用来存放原始原始的账号密码组合 Pairs 用来存经过编码的账号密码组合。 Basic Auth初始化的过程就是将 “账号:密码” 串经过base64编码之后存放在Pairs中。 func processCredentials(accounts Accounts) (Pairs, error) {if len(accounts) 0 {return nil, errors.New(Empty list of authorized credentials.)}pairs : make(Pairs, 0, len(accounts))for _, account : range accounts {if len(account.User) 0 || len(account.Password) 0 {return nil, errors.New(User or password is empty)}base : account.User : account.Passwordcode : Basic base64.StdEncoding.EncodeToString([]byte(base))pairs append(pairs, BasicAuthPair{code, account.User})}// We have to sort the credentials in order to use bsearch later.sort.Sort(pairs)return pairs, nil
}
复制代码在访问对应url的时候会提取auth字段然后将auth字段在我们保存的Pairs 中进行比对查找如果找到了就会返回对应的user func searchCredential(pairs Pairs, auth string) string {if len(auth) 0 {return }// Search user in the slice of allowed credentialsr : sort.Search(len(pairs), func(i int) bool { return pairs[i].Code auth })if r len(pairs) subtle.ConstantTimeCompare([]byte(pairs[r].Code), []byte(auth)) 1 {// user is allowed, set UserId to key user in this context, the userId can be read later using// c.Get(userreturn pairs[r].User}return
}
复制代码相应的 如果我们需要对一个 url 开启Basic Auth认证首先定义一个路由组调用对应的Basic Auth的中间件函数。 accounts : gin.Accounts{{User: admin, Password: password},{User: foo, Password: bar},}
authorized : r.Group(/auth, gin.BasicAuth(accounts))
复制代码然后把需要认证的url都挂在下边 authorized.GET(/secret, func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{secret: The secret url need to be authorized,})
})
复制代码这样当我们访问 /auth/secret 的时候就需要经过Basic Auth的认证。如果我们在浏览器端访问会弹出一个提示框要求输入账号和密码 如果是在 postman 等工具中访问 需要在header中添加一个 Authorization 字段字段的值是 “Basic 账号:密码的base64编码”。 比如账号是admin 密码是password 那么“admin:password” 经过base64编码的结果是“YWRtaW46cGFzc3dvcmQ” 所以对应的Authorization填的值应该是 “Basic YWRtaW46cGFzc3dvcmQ”。 Recovery Recovery在web框架中也是一个必不可少的中间件如果某个请求出现了panic服务需要捕获请求中的panic信息并且把信息打印到日志中有利于后期的维护和修复。 Recovery 其实就是定义了一个defer函数来处理请求中的panic在defer中会通过golang的recover() 函数catch住panic然后将对应的栈信息打印出来。 func Recovery() HandlerFunc {return func(c *Context) {defer func() {if len(c.Errors) 0 {log.Println(c.Errors)}if err : recover(); err ! nil {stack : stack(3)log.Printf(PANIC: %s\n%s, err, stack)c.Writer.WriteHeader(http.StatusInternalServerError)}}()c.Next()}
}
复制代码一般来说log中间件和recovery中间件都是必须的所以可以定义一个默认的框架初始化函数自动把log中间件和recovery中间件加载进去。 // Default Returns a Engine instance with the Logger and Recovery already attached.
func Default() *Engine {engine : New()engine.Use(Recovery(), Logger())return engine
}
复制代码至此一个简易版本的gin web框架就成型了包括最基本的日志功能、错误恢复、路由功能、认证功能等。当然也可以在这个基础之上在增加ORM等模块当是后续的功能扩展了。 完整的代码参见 github.com/harleylau/m…