基于Golang 和go mobile 实现统一Token认证

基于Golang一种语言实现统一的自定义Token认证算法,在服务器端(Golang开发api网关和api接口,基于gin),算法部分分离为私有go 库放在私有git上。算法库同时可以共享代码,编译为web assembly也可以通过go mobile编译为ios 和android 的库给客户端ios和android调用。

1. Golang私有库

设置你私有仓库的host name eg: git.mojotv.corp.net
设置你的私有仓库的UserName用户名
设置gitlab-access-token, 访问你 https://$GOPRIVATE/profile/personal_access_tokens 创建个人访问令牌,填写gitlab-access-token,进入Gitlab—>Settings—>Access Tokens,然后创建一个personal access token,这里权限最好选择只读(read_repository),git配置添加access token.
配置git config –global 使用access-token 验证私有仓库身份认证,来避免密码输入
现在你可以使用 go mod download (go run main.go)

#!/bin/bash -xv
# -xv shell脚本调试之用 这个参数也可以去掉

go env -w GOPROXY='https://goproxy.io' #加快 go mod 下载速度
echo '输入你私有仓库的host name eg: git.mojotv.corp.net >'

read GOPRIVATE

go env -w GOPRIVATE=$GOPRIVATE

echo '输入你的私有仓库的UserName用户名 >'

read GIT_USER
echo "访问你 https://$GOPRIVATE/profile/personal_access_tokens 创建个人访问令牌,填写gitlab-access-token >"
read GIT_TOKEN
echo '开始配置git config --global 使用access-token 验证私有仓库身份认证'
git config --global url."https://$GIT_USER:$GIT_TOKEN@$GOPRIVATE".insteadOf "https://$GOPRIVATE"
echo '现在你可以使用 go mod download (go run main.go) 继续开发你的项目吧'

2. Go mobile

Go mobile 是通过golang开发mobile应用的,可以将Golang编译为ios和android应用,也可以编译为framework和aar包。

安装:

go get golang.org/x/mobile/cmd/gomobile
gomobile init

编译IOS framework:

gomobile bind -target ios gitlab.imacco.com/dev/TokenLib

编译Android framework:

    export ANDROID_NDK_HOME=/Volumes/data/Android/NDK/
gomobile bind -target android gitlab.imacco.com/dev/TokenLib


3. Go wasm

Go 语言在 1.11 版本(2018年8月) 加入了对 WebAssembly (Wasm) 的原生支持,使用 Go 语言开发 WebAssembly 相关的应用变得更加地简单。Go 语言的内建支持是 Go 语言进军前端的一个重要的里程碑。在这之前,如果想使用 Go 语言开发前端,需要使用 GopherJS,GopherJS 是一个编译器,可以将 Go 语言转换成可以在浏览器中运行的 JavaScript 代码。新版本的 Go 则直接将 Go 代码编译为 wasm 二进制文件,而不再需要转为 JavaScript 代码。更巧的是,实现 GopherJS 和在 Go 语言中内建支持 WebAssembly 的是同一拨人。

编译:

GOOS=js GOARCH=wasm go build -o static/main.wasm

4. Gin 中间件拦截

package Web

import (
    "bytes"
    "github.com/gin-gonic/gin"
    "gitlab.imacco.com/dev/TokenLib"
    "io/ioutil"
    "strings"
)

func AuthMiddleWare() gin.HandlerFunc {

return func(c *gin.Context) {
    token := c.GetHeader("Token")
    deviceFingerPrinter := c.GetHeader("DeviceFingerPrint")

    defer func() {
        if r := recover(); r != nil {
            c.JSON(200, gin.H{
                "isSuccess": false,
                "data":      nil,
                "errmsg":    "Not Accept",
                "code":      403,
            })
            c.AbortWithStatus(200)
        }
    }()

    if token == "" || deviceFingerPrinter == "" {
        c.JSON(200, gin.H{
            "isSuccess": false,
            "data":      nil,
            "errmsg":    "Not Accept",
            "code":      403,
        })
        c.AbortWithStatus(200)
    } else {
        requestUrl := c.Request.RequestURI
        contentType := c.GetHeader("Content-Type")
        print(requestUrl)
        print(contentType)
        if !strings.Contains(contentType, "multipart") {
            //body, _ := c.GetRawData()
            var bodyBytes []byte // 我们需要的body内容

            // 从原有Request.Body读取
            bodyBytes, err := ioutil.ReadAll(c.Request.Body)
            if err != nil {
                panic(err)
            }

            // 新建缓冲区并替换原有Request.body
            c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))

            newToken := TokenLib.SignApiRequest(requestUrl, string(bodyBytes), deviceFingerPrinter)
            if newToken != token {
                c.JSON(200, gin.H{
                    "isSuccess": false,
                    "data":      nil,
                    "errmsg":    "Not Accept",
                    "code":      403,
                })
                c.AbortWithStatus(200)
            }
        } else {
            c.Next()
        }

    }
}
}

Lokie博客
请先登录后发表评论
  • 最新评论
  • 总共0条评论
  • 本博客使用免费开源的 laravel-bjyblog v5.5.1.1 搭建 © 2014-2018 lokie.wang 版权所有 ICP证:沪ICP备18016993号
  • 联系邮箱:kitche1985@hotmail.com