同学们好!成功登录《我家租房网》系统的用户,可以点击位于搜索页面右上角的用户名,进入用户页面。点击用户页面中的“实名认证”,会打开实名认证页面。在这里,填入真实姓名和身份证号后点击“保存”,系统后台会对用户输入的实名信息进行认证,并保存到数据库中。这些信息将不可被修改。本节课我们将实现这部分功能。


我们将首先实现支持实名认证的后端微服务,再在前端服务器中添加路由处理函数并远程调用后端微服务,最后再将前后端连在一起做完整的功能测试。


首先我们来实现后端服务器。


第一步是创建特定的微服务。


创建微服务的过程还是和先前一样,直接在back-end工程目录下执行go-micro命令,子命令为new,参数为service,微服务名为UserAuth。


接着,需要修改一下go-micro为我们自动生成的接口描述。在back-end工程目录下的UserAuth微服务目录中,有一个名为proto的子目录,这就是存放接口描述脚本及其Go代码文件的地方。现阶段里面只有一个名为UserAuth.proto的ProtoBuf脚本文件。我们需要对该文件做一些修改:

这段代码描述的是,前端服务器和后端微服务之间的数据交换格式。CallRequest表示前端提供给后端的请求数据,其中包含三个字符串,用户名、真实姓名和身份证号。CallResponse表示后端返回给前端的响应数据,其中包含错误代码和错误描述。


有了用ProtoBuf语言描述的远程调用接口,我们还需要把它编译成基于Go语言的程序代码。在UserAuth微服务目录中执行make命令,并携带四个目标参数,它们是init、proto、update和tidy。


在UserAuth微服务目录下,创建一个名为model的子目录,表示该微服务的模型层。在该子目录中创建mysql.go文件,封装所有与操作MySQL数据库有关的代码。在实际编写数据库访问代码之前,我们可以先把之前为前端服务器编写的mysql.go文件中的内容原封不动地复制到这里:


修改UserAuth微服务目录中的main.go文件,添加对InitDB函数的调用,将服务发现改为Consul,绑定IP地址和端口:

程序启动伊始,即完成对数据库的初始化。其中包括两个动作,其一是连接ihomedb数据库并获得连接池对象,其二是在该数据库中创建表。当然,如果这些表已经存在,则不再创建。接着,在服务器对象的初始化部分,指示其注册到Consul服务器,同时绑定本机的9009端口。


接下来,我们为UserAuth微服务编写与数据持久化有关的代码。


打开UserAuth微服务目录下,model子目录中的mysql.go文件,在其中添加有关更新MySQL数据库中的真实姓名和身份证号的代码:

定义名为UpdateRealnameAndIDCard的函数,用于更新MySQL数据库中的真实姓名和身份证号。该函数接收用户名、真实姓名和身份证号三个参数,以用户名为条件,更新用户表中特定记录的真实姓名和身份证号字段,并将错误对象返回给函数的调用者。注意这里使用的Updates方法可以同时更新多个字段,每个字段的名值对应,以字符串到空接口的映射形式表示。


在完成UserAuth微服务模型层的所有开发工作之后,我们将着手编写用于处理实名认证业务的代码。


打开UserAuth微服务目录下,handler子目录中的UserAuth.go文件,在其中的Call方法里,添加与实名认证有关的操作:

这里首先调用第三方接口,验证请求对象中的真实姓名和身份证号是否匹配,若匹配则调用模型层的UpdateRealnameAndIDCard函数,更新MySQL数据库中的真实姓名和身份证号,最后将错误代码和错误描述存入响应对象并返回。涉及身份认证的第三方接口,通常由公安、银联、征信等权威机构授权提供,同学们可自行从相关渠道获得开发接口,合法使用。


在完成UserAuth后端服务器的开发后,我们需要为前端服务器添加一条路由,并在路由处理函数中完成对后端微服务远程方法的调用。


前端和后端共用同一套接口描述。


因此,这里我们将UserAuth微服务目录下proto子目录中的所有文件,原封不动地复制到front-end工程目录proto子目录下的UserAuth目录中。


这里我们要为实名认证添加一条路由,POST方法结合/api/v1.0/user/auth路径,处理函数名为UserAuth。同学们也许还记得,在之前的课程里,我们曾经为获取用户信息添加过一条路由,GET方法结合/api/v1.0/user路径,处理函数名为GetUser。GetUser处理函数向浏览器返回的响应中也包括用户的真实姓名和身份证号。因此在有关获取认证的路由中,我们可以将GET方法结合/api/v1.0/user/auth路径,再次路由到GetUser处理函数。


在front-end工程目录下的main.go文件中添加两条路由:

我们首先调用了路由对象的POST方法,为实名认证添加了一条路由,将POST方法结合/user/auth路径,路由到controller包的UserAuth函数,接着又调用了路由对象的GET方法,为获取认证添加了一条路由,将GET方法结合/user/auth路径,路由到controller包的GetUser函数。将UserAuth函数定义在controller包里是因为该函数的主要任务是执行业务逻辑,属于MVC中的C,即控制器层的部分。


当然,在controller包里真的得有UserAuth函数。为此,我们打开front-end工程目录下controller子目录中的user.go文件。在该文件的import部分增加一行,同时定义UserAuth函数:

这段代码首先从Session中读取用户名,接着对请求包体中的JSON字符串做反序列化,得到用户的真实姓名和身份证号。通过Consul服务发现,获取有关名为userauth的微服务的信息,远程调用其中的UserAuth对象的Call方法。该方法以包含用户名、真实姓名和身份证号的请求对象为参数,并返回包含错误代码和错误描述的响应对象。最后将该响应对象序列化为一个JSON字符串,编码到HTTP响应中,回传给浏览器。


至此,我们已经完成实名认证的全部开发工作。下面我们将对这部分功能进行测试。


启动Consul服务器、UserLogin、GetUser、UserAuth后端微服务和前端服务器。通过登录页面登录系统,点击位于搜索页面右上角的用户名,进入用户页面,点击“实名认证”,进入实名认证页面,填入真实姓名和身份证号,点击“保存”,提示保存成功。再次进入实名认证页面,可以看到之前输入的真实姓名和身份证号,以只读方式显示在认证信息栏中。


谢谢大家,我们下节课再见!