美文网首页
go-micro网关鉴权之jwt

go-micro网关鉴权之jwt

作者: niyiwei | 来源:发表于2020-02-20 16:11 被阅读0次

go-micro 提供一个工具包micro在micro中提供api网关功能

需要重写micro才能进行鉴权,否则在每一个服务都做鉴权是一件很麻烦的事情。

提供的 github上 go-plugins中 包含micro权限插件


image-20200220131044118.png

我们现在需要使用的是 jwt鉴权

所以我们需要自己实现

type Handler func(http.Handler) http.Handler

这个接口方法

jwt:

func JWTAuthWrapper(t *token.Token) plugin.Handler {
    return func(h http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

            //不需要登录的url地址 strings.HasPrefix(r.URL.Path, "/hello") ||
            if r.URL.Path == "/metrics" ||
                r.URL.Path == "/user/login" ||
                r.URL.Path == "/user/register" {
                h.ServeHTTP(w, r)
                return
            }

            tokenstr := r.Header.Get("Authorization")
            userFromToken, e := t.Decode(tokenstr)

            if e != nil {
                _, _ = w.Write(unauthorized)
                return
            }

            r.Header.Set("X-Example-Username", userFromToken.UserName)
            h.ServeHTTP(w, r)
        })
    }
}

token:

package token

import (
    "time"
    "log"
    "sync"

    jwt "github.com/dgrijalva/jwt-go"
    config "github.com/micro/go-micro/config"
)

// CustomClaims 自定义的 metadata在加密后作为 JWT 的第二部分返回给客户端
type CustomClaims struct {
    UserName string `json:"user_name"`
    jwt.StandardClaims
}

// Token jwt服务
type Token struct {
    rwlock     sync.RWMutex
    privateKey []byte
    conf       config.Config
}

func (srv *Token) get() []byte {
    srv.rwlock.RLock()
    defer srv.rwlock.RUnlock()

    return srv.privateKey
}

func (srv *Token) put(newKey []byte) {
    srv.rwlock.Lock()
    defer srv.rwlock.Unlock()

    srv.privateKey = newKey
}

// InitConfig 初始化
func (srv *Token) InitConfig(address string, path ...string) {
    srv.put([]byte("秘钥"))
}

func (srv *Token) enableAutoUpdate(path ...string) {
    go func() {
        for {
            w, err := srv.conf.Watch(path...)
            if err != nil {
                log.Println(err)
            }
            v, err := w.Next()
            if err != nil {
                log.Println(err)
            }

            value := v.Bytes()
            srv.put(value)
            log.Println("New JWT privateKey:", string(srv.get()))
        }
    }()
}

//Decode 解码
func (srv *Token) Decode(tokenStr string) (*CustomClaims, error) {
    t, err := jwt.ParseWithClaims(tokenStr, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
        return srv.get(), nil
    })

    if err != nil {
        return nil, err
    }
    // 解密转换类型并返回
    if claims, ok := t.Claims.(*CustomClaims); ok && t.Valid {
        return claims, nil
    }

    return nil, err
}

// Encode 将 User 用户信息加密为 JWT 字符串
// expireTime := time.Now().Add(time.Hour * 24 * 3).Unix() 三天后过期
func (srv *Token) Encode(issuer, userName string, expireTime int64) (string, error) {
    claims := CustomClaims{
        userName,
        jwt.StandardClaims{
            Issuer:    issuer,
            IssuedAt:  time.Now().Unix(),
            ExpiresAt: expireTime,
        },
    }

    jwtToken := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
    return jwtToken.SignedString(srv.get())
}

后面就是注册到micro的服务中了,

    import (
        "github.com/micro/micro/plugin"
    )
    
    
    tk := &token.Token{}
    _ = plugin.Register(plugin.NewPlugin(
        plugin.WithName("auth"),
        plugin.WithHandler(
            auth.JWTAuthWrapper(tk),
        ),
        plugin.WithFlag(cli.StringFlag{
            Name:   "consul_address",
            Usage:  "consul address for K/V",
            EnvVar: "CONSUL_ADDRESS",
            Value:  "127.0.0.1:8500",
        }),
        plugin.WithInit(func(ctx *cli.Context) error {
            log.Println(ctx.String("consul_address"))
            tk.InitConfig(ctx.String("consul_address"), "micro", "config", "jwt-key", "key")
            return nil
        }),
    ))

相关文章

  • go-micro网关鉴权之jwt

    go-micro 提供一个工具包micro在micro中提供api网关功能 需要重写micro才能进行鉴权,否则在...

  • JWT鉴权 Session鉴权

    JWT鉴权:image.png session鉴权:image.png

  • Koa 使用 JWT 实现鉴权

    JWT 鉴权的优势 JWT (JSON Web Token) 是现今比较主流的的登录鉴权方式。token 类似一个...

  • JWT 鉴权

    JWT 是什么 JSON Web Token(JWT)是一个开放式标准(RFC 7519),它定义了一种紧凑且自包...

  • JWT 鉴权

    使用 koa-jwt + jsonwebtoken 完成用户鉴权功能。项目地址:https://github.co...

  • jwt鉴权

    什么是JWT(Json web token): JWT是目前最流行的跨域认证解决方案。基于json的开放标准(R...

  • 前端鉴权和缓存相关收藏

    Auth2鉴权 JWT cookie-session 缓存相关

  • JWT

    概述 JWT 基于 token 的鉴权机制,基于 token 的鉴权机制类似于 http 协议也是无状态的,它不需...

  • spring-cloud-gateway网关鉴权

    spring-cloud-gateway中的filter进行网关鉴权

  • 鉴权

    常见的鉴权方式:Session/Cookie、Token(JWT)、OAuth、SSO Session/Cooki...

网友评论

      本文标题:go-micro网关鉴权之jwt

      本文链接:https://www.haomeiwen.com/subject/rjbxqhtx.html