如何将我的服务开放给用户: 构建 API 接口和用户认证的实践指南
实践内容:
本次实践旨在模拟一个业务逻辑与接口层逻辑分离的程序。本程序使用了GORM框架,详见上一篇笔记: [juejin.cn/post/727085…] 在接口层提供了用户登陆、注册、查看个人信息等功能的接口。我将对用户进行JWT鉴权。
原理说明:
- 鉴权
为了保证数据安全,不管是服务方还是用户方,不同安全等级的服务的使用者/运维者需要具备相应的权限。对于用户,绝大多数社交软件的要求,都是只有已经注册的用户才拥有在平台上与服务方或者其他用户互动的权限。对于用户鉴权,常用方式包括HTTP Authentification,session-Cokkie,Token令牌等方式[1]。其中JWT鉴权属于使用Token的范畴。 每次用户登陆时,服务端并非直接在数据库中进行密码的对比,因为这样既占用大量资源,而且频繁传输用户的密码信息也是极其不安全的。解决方式之一是使用Token:当用户注册成功后,服务端将储存用户的信息,同时生成一条独属于此用户的加密信息Token并储存下来,传回给用户。在下一次用户登陆时,使用Token进行校验。这个过程中仍然存在一定的风险,但是其安全性对于小型的服务是完全满足的。
实践过程:
- 完善程序结构:
添加Handlers, Functions 分别存放接口与业务逻辑。DataBase为GORM框架下的数据库操作与连接。
- 重新定义数据模型:
物理删除数据库信息:
定义新的模型--
在原有的用户结构体中,添加Token和UID[2]
UID设定为13位随机字符串,并将其设置为主表的主键,方便未来添加用户之间交互时的功能。
Password string `gorm:"size:255;not null" json:"password"`
Token string `gorm:"size:255;not null" json:"token"`
ID int64 `gorm:"user_id" json:"user_id"`
-
请求编写:
首先,我将接口与业务逻辑放在Handlers文件夹下一起编写,这样暂时比较容易进行调试。测试无误之后再将业务与接口分离。
使用 golang.org/x/crypto v0.12.0 将密码加密后存入数据库。使用github.com/dgrijalva/j… 进行JWT鉴权。
-
提供用户层接口:
我们的目的是用户从前端输入正确格式的用户名和有效密码,这些信息被加密后,通过HTTP方法(接口)上传到服务端,进行储存和Token生成再由HTTP响应通知用户注册的结果。 Go语言的net/http库中的http.HandleFunc()函数,使我们能够通过结构体传入请求信息,最后生成一个链接共客户端使用。我们使用http.ListenAndServe()函数,传入服务器监听用户请求的地址和端口。在这里我使用的是本机的ip地址及默认端口。
补充:MacOS 中可以在终端通过 ifconfig |grep inet 命令查看ip地址。 -
分离业务逻辑与接口:
在用户注册这一功能中,业务逻辑包括为检验用户输入信息是否合规,密码加密,以及生成Token。接口逻辑只包括将请求的数据和响应数据格式化并进行数据库连接、用户层连接。
引用资料:
[1] [blog.csdn.net/gofuncchan/…] (系统鉴权概述)
[2] gorm.io 官方文档