当前位置:网站首页>Kratos ares microservice framework (III)
Kratos ares microservice framework (III)
2022-07-06 09:13:00 【~Pompeii】
Catalog
Kratos Ares microservice framework ( 3、 ... and )
middleware
package auth
import (
"context"
"errors"
"fmt"
"github.com/davecgh/go-spew/spew"
"github.com/golang-jwt/jwt/v4"
"strings"
"time"
"github.com/go-kratos/kratos/v2/middleware"
"github.com/go-kratos/kratos/v2/transport"
)
func GenerateToken(secret, username string) string {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"username": username,
"nbf": time.Date(2015, 10, 10, 12, 0, 0, 0, time.UTC).Unix(),
})
// Sign and get the complete encoded token as a string using the secret
tokenString, err := token.SignedString([]byte(secret))
if err != nil {
panic(err)
}
fmt.Println(tokenString, err)
return tokenString
}
func JWTAuth(secret string) middleware.Middleware {
return func(handler middleware.Handler) middleware.Handler {
return func(ctx context.Context, req interface{
}) (reply interface{
}, err error) {
if tr, ok := transport.FromServerContext(ctx); ok {
tokenString := tr.RequestHeader().Get("Authorization")
auths := strings.SplitN(tokenString, " ", 2)
if len(auths) != 2 || !strings.EqualFold(auths[0], "Token") {
return nil, errors.New("jwt token missing")
}
token, err := jwt.Parse(auths[1], func(token *jwt.Token) (interface{
}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("err %v", token)
}
return []byte(secret), nil
})
if err != nil {
return nil, err
}
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
spew.Dump(claims["username"])
} else {
return nil, errors.New("Token Invalid")
}
}
return handler(ctx, req)
}
}
}
func NewHTTPServer(c *conf.Server, jwtc *conf.JWT, greeter *service.RealWorldService, logger log.Logger) *http.Server {
var opts = []http.ServerOption{
http.ErrorEncoder(errorEncoder),
http.Middleware(
recovery.Recovery(),
selector.Server(auth.JWTAuth(jwtc.Token)).Match(NewSkipRoutersMatcher()).Build(), // Add selector filter
//auth.JWTAuth(jwtc.Token),
),
http.Filter(handlers.CORS( // Solving cross domain problems
handlers.AllowedHeaders([]string{
"X-Requested-With", "Content-Type", "Authorization"}),
handlers.AllowedMethods([]string{
"GET", "POST", "PUT", "HEAD", "OPTIONS"}),
handlers.AllowedOrigins([]string{
"*"}),
)),
}
if c.Http.Network != "" {
opts = append(opts, http.Network(c.Http.Network))
}
if c.Http.Addr != "" {
opts = append(opts, http.Address(c.Http.Addr))
}
if c.Http.Timeout != nil {
opts = append(opts, http.Timeout(c.Http.Timeout.AsDuration()))
}
srv := http.NewServer(opts...)
v1.RegisterRealWorldHTTPServer(srv, greeter)
return srv
}
Implement middleware filtering
func NewSkipRoutersMatcher() selector.MatchFunc {
skipRouters := make(map[string]struct{
})
skipRouters["/realworld.v1.RealWorld/Login"] = struct{
}{
} // jwt Filter login and register
skipRouters["/realworld.v1.RealWorld/Register"] = struct{
}{
}
return func(ctx context.Context, operation string) bool {
if _, ok := skipRouters[operation]; ok {
return false
}
return true
}
}
Solving cross domain problems
http.Filter(handlers.CORS(
handlers.AllowedHeaders([]string{
"X-Requested-With", "Content-Type", "Authorization"}),
handlers.AllowedMethods([]string{
"GET", "POST", "PUT", "HEAD", "OPTIONS"}),
handlers.AllowedOrigins([]string{
"*"}),
)),
// NewHTTPServer new a HTTP server.
func NewHTTPServer(c *conf.Server, jwtc *conf.JWT, greeter *service.RealWorldService, logger log.Logger) *http.Server {
var opts = []http.ServerOption{
http.ErrorEncoder(errorEncoder),
http.Middleware(
recovery.Recovery(),
selector.Server(auth.JWTAuth(jwtc.Token)).Match(NewSkipRoutersMatcher()).Build(),
//auth.JWTAuth(jwtc.Token),
),
http.Filter(handlers.CORS( // To solve the cross domain
handlers.AllowedHeaders([]string{
"X-Requested-With", "Content-Type", "Authorization"}),
handlers.AllowedMethods([]string{
"GET", "POST", "PUT", "HEAD", "OPTIONS"}),
handlers.AllowedOrigins([]string{
"*"}),
)),
}
if c.Http.Network != "" {
opts = append(opts, http.Network(c.Http.Network))
}
if c.Http.Addr != "" {
opts = append(opts, http.Address(c.Http.Addr))
}
if c.Http.Timeout != nil {
opts = append(opts, http.Timeout(c.Http.Timeout.AsDuration()))
}
srv := http.NewServer(opts...)
v1.RegisterRealWorldHTTPServer(srv, greeter)
return srv
}
Custom error
package errors
import (
"errors"
"fmt"
)
type HTTPError struct {
Errors map[string][]string `json:"errors"`
Code int `json:"-"`
}
func NewHTTPError(code int, field string, detail string) *HTTPError {
return &HTTPError{
Code: code, Errors: map[string][]string{
field: {
detail},
}}
}
func (e *HTTPError) Error() string {
return fmt.Sprintf("HTTPError %d", e.Code)
}
func FromError(err error) *HTTPError {
if err == nil {
return nil
}
if se := new(HTTPError); errors.As(err, &se) {
return se
}
return &HTTPError{
}
}
package server
import (
"github.com/go-kratos/kratos/v2/transport/http"
e "helloworld/internal/errors"
stdhttp "net/http"
)
func errorEncoder(w stdhttp.ResponseWriter, r *stdhttp.Request, err error) {
se := e.FromError(err)
codec, _ := http.CodecForRequest(r, "Accept")
body, err := codec.Marshal(se)
if err != nil {
w.WriteHeader(500)
return
}
w.Header().Set("Content-Type", "application/"+codec.Name())
w.WriteHeader(se.Code)
_, _ = w.Write(body)
}
Use :
func (s *RealWorldService) Login(ctx context.Context, req *v1.LoginRequest) (*v1.UserReply, error) {
if len(req.User.Email) == 0 {
return nil, errors.NewHTTPError(422, "email", "can't be empty")
}
return &v1.UserReply{
User: &v1.UserReply_User{
Username: "jjj",
},
}, nil
}
边栏推荐
- 【每日一题】搬运工 (DFS / DP)
- LeetCode:836. Rectangle overlap
- 不同的数据驱动代码执行相同的测试场景
- Leetcode problem solving 2.1.1
- Advance Computer Network Review(1)——FatTree
- The carousel component of ant design calls prev and next methods in TS (typescript) environment
- Compétences en mémoire des graphiques UML
- QML control type: menu
- 注意力机制的一种卷积替代方式
- [OC]-<UI入门>--常用控件-提示对话框 And 等待提示器(圈)
猜你喜欢
Kratos战神微服务框架(二)
MongoDB 的安装和基本操作
KDD 2022论文合集(持续更新中)
[OC]-<UI入门>--常用控件-提示对话框 And 等待提示器(圈)
Pytest参数化你不知道的一些使用技巧 /你不知道的pytest
Chapter 1 :Application of Artificial intelligence in Drug Design:Opportunity and Challenges
Once you change the test steps, write all the code. Why not try yaml to realize data-driven?
【剑指offer】序列化二叉树
Cesium draw points, lines, and faces
I-BERT
随机推荐
Chapter 1 :Application of Artificial intelligence in Drug Design:Opportunity and Challenges
Leetcode: Jianzhi offer 04 Search in two-dimensional array
Pytest参数化你不知道的一些使用技巧 /你不知道的pytest
[oc foundation framework] - < copy object copy >
Li Kou daily question 1 (2)
Parameterization of postman
postman之参数化详解
多元聚类分析
KDD 2022论文合集(持续更新中)
[OC foundation framework] - string and date and time >
甘肃旅游产品预订增四倍:“绿马”走红,甘肃博物馆周边民宿一房难求
Selenium+pytest automated test framework practice
CSP salary calculation
数字人主播618手语带货,便捷2780万名听障人士
pytorch查看张量占用内存大小
数学建模2004B题(输电问题)
What is MySQL? What is the learning path of MySQL
QML type: overlay
Selenium+Pytest自动化测试框架实战(下)
Redis之Bitmap