• 微服务从代码到k8s部署应有尽有系列(三、鉴权)


    我们用一个系列来讲解从需求到上线、从代码到k8s部署、从日志到监控等各个方面的微服务完整实践。

    整个项目使用了go-zero开发的微服务,基本包含了go-zero以及相关go-zero作者开发的一些中间件,所用到的技术栈基本是go-zero项目组的自研组件,基本是go-zero全家桶了。

    实战项目地址:https://github.com/Mikaelemmmm/go-zero-looklook

    1、鉴权服务

    1.1 identity-api

    identity主要是用来做鉴权服务的,前面我们nginx网关的时候有提到。在访问一个资源的时候,nginx内部会先来identity-api中解析token,identity-api会去请求identity-rpc,所有的验证与颁发token,统一是在identity-rpc中做的

    我们会从header的Authorization中获取token,从x-Original-Uri获取访问的资源路径

    • 如果当前访问的路由需要登陆:
      • token解析失败:就会返回给前端http401错误码;
      • token解析成功:就会将解析出来的userId放入header的x-user中返回给auth模块,auth模块会把header传递给对应访问的服务(usercenter), 这样我们在usercenter直接就可以拿到该登陆用户的id了
    • 如果当前访问的路由不需要登陆:
      • 前端header中传递了token
        • 如果token校验失败:返回http401;
        • 如果token校验成功:就会将解析出来的userId放入header的x-user中返回给auth模块,auth模块会把header传递给对应访问的服务(usercenter), 这样我们在usercenter直接就可以拿到该登陆用户的id了
      • 前端header中没传递token:userid 会传递 0 给后端服务

    urlNoAuth方法判断当前资源是否在yml中配置可以不登陆

    //当前url是否需要授权验证
    func (l *TokenLogic) urlNoAuth(path string) bool {
       for _, val := range l.svcCtx.Config.NoAuthUrls {
          if val == path {
             return true
          }
       }
       return false
    }
    

    isPass方法就是去identity-rpc校验token,主要也是使用了go-zero的jwt的方法

    1.2 identity-rpc

    当我们在注册、登陆成功时候,用户服务会调用identity-rpc生成token,所以我们统一在identity-rpc中颁发、校验token,这样就不用每个服务都要写个jwt去维护。

    当identity-api请求进来时候,identity-api自己可以解析出来userid,但是我们要检验这个token是否是过期,就要去后端rpc中的redis中去进行二次校验(当然如果你觉得这里多一次请求,你可以把这一步放到api里直接请求redis也可以),经过rpc的validateToken方法校验

    message ValidateTokenReq {
      int64 userId = 1;
      string token = 2;
    }
    message ValidateTokenResp {
      bool ok = 1;
    }
    
    rpc validateToken(ValidateTokenReq) returns(ValidateTokenResp);
    

    校验之前登陆、注册等授权时候颁发出去存在redis的token是否正确、过期。

    这样api就可以返回给nginx的auth模块是否失败,如果失败auth会直接返回给前端http code 401(所以你们前端应该是先判断http状态码>=400全部异常,再判断业务错误码) , 如果成功直接访问后端服务了拿到数据直接返回给前端展示

    2、安装goctl 与 protoc、protoc-gen-go

    【注】这个跟鉴权没什么关系,只是后面写代码要用到,在这里最好给安装了

    2.1 安装goctl

    # for Go 1.15 and earlier
    GO111MODULE=on GOPROXY=https://goproxy.cn/,direct go get -u github.com/zeromicro/go-zero/tools/goctl@latest
    
    # for Go 1.16 and later
    GOPROXY=https://goproxy.cn/,direct go install github.com/zeromicro/go-zero/tools/goctl@latest
    

    验证是否安装成功

    $ goctl --version
    

    Goctl自定义模版template:将项目目录下的data/goctl文件夹内容copy到 HOME 目录的 .goctl 中,goctl在生成代码时候会优先根据这个模版下内容生成

    $ cp -r data/goctl ~/.goctl
    

    2.2 安装protoc

    链接:https://github.com/protocolbuffers/protobuf/releases

    直接找到对应平台的protoc,我是mac intel芯片,所以直接找到 protoc-3.19.3-osx-x86_64.zip ,解压出来后进入该目录下的bin目录中,将protoc直接copy到你的gopath/bin目录下即可。

    验证是否安装成功

    $ protoc --version
    

    2.3 安装protoc-gen-go

    $ GOPROXY=https://goproxy.cn/,direct go install google.golang.org/protobuf/cmd/protoc-gen-go@latest 
    

    查看$GOPATH/bin下是否有protoc-gen-go即可

    【注】:如果后续在使用goctl生成代码时候,遇到以下问题

    protoc  --proto_path=/Users/seven/Developer/goenv/go-zero-looklook/app/usercenter/cmd/rpc/pb usercenter.proto --go_out=plugins=grpc:/Users/seven/Developer/goenv/go-zero-looklook/app/usercenter/cmd/rpc --go_opt=Musercenter.proto=././pb
    goctl: generation error: unsupported plugin protoc-gen-go which installed from the following source:
    google.golang.org/protobuf/cmd/protoc-gen-go, 
    github.com/protocolbuffers/protobuf-go/cmd/protoc-gen-go;
    
    Please replace it by the following command, we recommend to use version before v1.3.5:
    go get -u github.com/golang/protobuf/protoc-gen-go
    goctl version: 1.3.0 darwin/amd64
    

    直接执行

    $ GOPROXY=https://goproxy.cn/,direct go get -u github.com/golang/protobuf/protoc-gen-go
    

    2.4 安装protoc-gen-go-grpc

    $ GOPROXY=https://goproxy.cn/,direct go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
    

    3、总结

    总的来说,identity还算是比较简单的,整个流程如下:

    用户发起请求资源 -> nginx网关->匹配到对应服务模块 -> auth模块->identity-api ->identity-rpc -> 用户请求的资源

    项目地址

    https://github.com/zeromicro/go-zero

    欢迎使用 go-zerostar 支持我们!

    微信交流群

    关注『微服务实践』公众号并点击 交流群 获取社区群二维码。

  • 相关阅读:
    react路由,路由配置写在哪里?
    fastadmin中自建留言板的总结(一)TP5.0的数据流程
    精通JS的调试之控制台api大全,抓住数据的本质,本质!本质!!
    react中的,invoke,evoke,dispatch,assign都是什么意思,有什么区别
    leetcode——215.数组中的第k个最大的数
    leetcode——53.最大子序和
    leetcode——441.排列硬币
    leetcode——1137.第N个斐波那契数
    leetcode——70.爬楼梯
    leetcode——509.斐波那契数
  • 原文地址:https://www.cnblogs.com/kevinwan/p/15907670.html
Copyright © 2020-2023  润新知