本篇介绍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("user"return 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…

仿Gin搭建自己的web框架(七)相关推荐

  1. 仿Gin搭建自己的web框架(五)

    继续扩展web框架的功能. context作为某个请求的上下文,必然就需要承担它最基本的功能:在各个中间件和函数之间传递变量.所以我们在context的结构体定义中加入一个Keys的字段,用来放置上下 ...

  2. gin 项目结构_Go Web 框架 Gin 路由的学习

    Gin 是目前应用比较广泛的Golang web 框架.目前,Github Star 数已经达到了3.8w. 框架的实现非常简单,可定制性非常强,性能也比较好,深受golang开发者的喜爱.Gin 提 ...

  3. Python框架篇之Django(Django项目搭建全过程、Web框架与Django)

    文章目录 一.Web框架与Django本质 二.从安装到实现一个完整的Django项目 一.Web框架与Django本质 1.Web框架的理解 框架,特指为解决一个开放性问题而设计的具有一定约束性的支 ...

  4. go java web框架_java程序员10分钟可上手的golang框架golang实战使用gin+xorm搭建go语言web框架restgo...

    1.首先上效果 是不是想起spring MVC? cd $GOPATH/src git clone https://github.com/winlion/restgo-admin.git 你将得到re ...

  5. golang web 框架 gin beego iris 对比

    1.1 框架排名 Gin 31k [Lite] Beego 22k Iris 16k Echo 15k [Lite] Revel 11k Martini 10k [×] buffalo 5k [Lit ...

  6. python搭建django框架,Python之Web框架Django项目搭建全过程

    Python之Web框架Django项目搭建全过程 IDE说明: Win7系统 Python:3.5 Django:1.10 Pymysql:0.7.10 Mysql:5.5 注:可通过pip fre ...

  7. Go 语言web 框架 Gin 练习8

    目录 文章目录 1 介绍 2 练习 友情援助 1 介绍 Gin是一个golang的微框架,封装比较优雅,API友好,源码注释比较明确,具有快速灵活,容错方便等特点 对于golang而言,web框架的依 ...

  8. Go 语言web 框架 Gin 练习 7

    目录 文章目录 1 介绍 2 练习 友情援助 1 介绍 Gin是一个golang的微框架,封装比较优雅,API友好,源码注释比较明确,具有快速灵活,容错方便等特点 对于golang而言,web框架的依 ...

  9. Go 语言web 框架 Gin 练习6

    目录 文章目录 1 介绍 2 练习 结果展示 友情援助 1 介绍 Gin是一个golang的微框架,封装比较优雅,API友好,源码注释比较明确,具有快速灵活,容错方便等特点 对于golang而言,we ...

最新文章

  1. python中 __name__及__main()__的妙处02
  2. N的阶乘末尾有多少个0
  3. linux下系统安全常见问题2
  4. POJ-1050 To the Max 二维最大子段和
  5. 关于onload的事件权柄以及踩过的坑
  6. 傅里叶变换对噪声进行频谱分析
  7. 【直播预告】腾讯广告实时策略数据框架建设
  8. android自定义协议,Android / iOS-自定义URI /协议处理
  9. 高频JMeter软件测试面试题
  10. Linux串口驱动(5) - read详解
  11. 学生DW网页设计作业成品——电商购物网站设计(55页) 电商网页设计制作 简单静态HTML网页作品 购物网页作业成品 学生商城网站模板
  12. matlab 超像素合并,超像素区域合并
  13. 【华为云技术分享】漫谈LIteOS-物联网操作系统介绍
  14. PuTTY 远程连接 Linux 服务器
  15. 计算机音乐创作心得,理结与悠的作曲入门讲座(心得篇 3-4)
  16. 世界50所知名大学开放课程列表及对应网站
  17. GEM5教程: 使用 gem5 运行 PARSEC 基准测试
  18. 什么叫死区时间_死区时间控制
  19. 企业级解决SQL注入、XSS攻击解决案例
  20. java 管道设计_设计模式——管道模式

热门文章

  1. 小米max2 android p,这就是小米Max2?6.4英寸超大屏幕配置大升级
  2. 腾讯正式宣布成立技术委员会,要对组织架构下狠手
  3. Numpy的常用方法
  4. JAVA企业级应用TOMCAT实战视频课程
  5. Centos6.3下DRBD+HeartBeat+NFS配置笔记
  6. kubeadm部署k8s_用 kubeadm 部署生产级 k8s 集群
  7. (24) 不可能的出栈顺序
  8. labelme2coco问题:TypeError: Object of type 'int64' is not JSON serializable
  9. Day10:html和css
  10. Spring boot整合Mongodb