?Auth
?中間件用于認證請求。只有通過認證的請求才能被處理,結(jié)合 ?selector
?中間件可實現(xiàn)白名單。目前提供基于JWT認證的中間件。
需要配置 ?
JWT
? 秘鑰生成函數(shù)。
httpSrv := http.NewServer(
http.Address(":8000"),
http.Middleware(
jwt.Server(func(token *jwtv4.Token) (interface{}, error) {
return []byte(testKey), nil
}),
),
)
grpcSrv := grpc.NewServer(
grpc.Address(":9000"),
grpc.Middleware(
jwt.Server(func(token *jwtv4.Token) (interface{}, error) {
return []byte(testKey), nil
}),
),
)
需要配置 ?
JWT
? 秘鑰生成函數(shù)。
conn, err := http.NewClient(
context.Background(),
http.WithEndpoint("127.0.0.1:8000"),
http.WithMiddleware(
jwt.Client(func(token *jwtv4.Token) (interface{}, error) {
return []byte(serviceTestKey), nil
}),
),
)
con, _ := grpc.DialInsecure(
context.Background(),
grpc.WithEndpoint("xxx.xxx.domain"),
grpc.WithMiddleware(
jwt.Client(func(token *jwtv4.Token) (interface{}, error) {
return []byte(serviceTestKey), nil
}),
),
)
WithSigningMethod()
?用于配置?JWT
?簽名的算法。適用于 ?server
?和 ?client
?。
例如:
import jwtv4 "github.com/golang-jwt/jwt/v4"
jwt.WithSigningMethod(jwtv4.SigningMethodHS256)
WithClaims()
?用于配置 ?JWT
?的 ?claims
?。
例如:
配置 ?client
?的 ?claims
?:
注意:?
server
?的 ?claims
?和 ?client
?的配置方式有一定的區(qū)別,?server
?必須返回一個新對象。目的為了避免出現(xiàn)并發(fā)寫的問題。
jwt.WithClaims(func()jwtv4.Claims{return &jwtv4.StandardClaims{}})
一個簡易的 demo,包含了 ?server
?和 ?client
?的使用。
其中 ?client
?配置的是另外一個監(jiān)聽了9001的服務(wù),并且該服務(wù)的key和這里配置的 ?serviceTestKey
?一樣。
con, _ := grpc.DialInsecure(
context.Background(),
grpc.WithEndpoint("dns:///127.0.0.1:9001"), // 本地的9001服務(wù)
grpc.WithMiddleware(
jwt.Client(func(token *jwtv4.Token) (interface{}, error) {
return []byte(serviceTestKey), nil
}),
),
)
使用者可通過提供的接口 ?jwt.FromContext(ctx)
? 獲取用戶信息。
帶有 ?JWT Token
? 的請求,經(jīng)過 ?server
?側(cè)的 ?jwt
?中間件后,?token
?的 ?claims
?會放進上下文 ?context
?中。
此時使用者通過提供的接口 ?jwt.FromContext(ctx)
? 即可獲取上下文中的 ?claims
?對象,而一般用戶信息是存儲在 ?claims
?里面的。使用者需要對 ?claims
?斷言后才能進一步處理,?claims
?類型的定義偏業(yè)務(wù)性質(zhì),和?token
?簽發(fā)的業(yè)務(wù)耦合。簽發(fā)時使用的類型,這里就需要斷言對應(yīng)的類型。
接口原型:
func FromContext(ctx context.Context) (token jwt.Claims, ok bool)
結(jié)合 ?selector
?中間件使用實現(xiàn)白名單機制??蓞⒖迹?a href="http://m.hgci.cn/targetlink?url=https://github.com/go-kratos/beer-shop/blob/a29eae57a9baeae9969e9a7d418ff677cf494a21/app/shop/interface/internal/server/http.go#L41" target="_blank">https://github.com/go-kratos/beer-shop/blob/a29eae57a9baeae9969e9a7d418ff677cf494a21/app/shop/interface/internal/server/http.go#L41
注意:這里簽發(fā)的 ?
JWT Token
? 只是用于服務(wù)間簡單認證,并不能作為業(yè)務(wù)令牌使用。因此也沒有開放簽發(fā)的接口,業(yè)務(wù)令牌需要使用者根據(jù)實際業(yè)務(wù)自行實現(xiàn)簽發(fā)邏輯。
?Token
?的簽發(fā)發(fā)生在 ?client
?側(cè),使用者確保 ?client
?和 ?server
?使用相同的 ?Key
?和簽名算法即可。簽發(fā)時附帶的用戶信息或者其他信息可以通過 ?WithClaims()
? 來配置。
更多建議: