当前位置:网站首页>Kratos战神微服务框架(三)
Kratos战神微服务框架(三)
2022-07-06 08:59:00 【~庞贝】
Kratos战神微服务框架(三)
中间件
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(), //添加选择器过滤
//auth.JWTAuth(jwtc.Token),
),
http.Filter(handlers.CORS( // 解决跨域问题
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
}
实现中间件过滤
func NewSkipRoutersMatcher() selector.MatchFunc {
skipRouters := make(map[string]struct{
})
skipRouters["/realworld.v1.RealWorld/Login"] = struct{
}{
} // jwt过滤login和register
skipRouters["/realworld.v1.RealWorld/Register"] = struct{
}{
}
return func(ctx context.Context, operation string) bool {
if _, ok := skipRouters[operation]; ok {
return false
}
return true
}
}
解决跨域问题
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( // 解决跨域
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
}
自定义错误
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)
}
使用:
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
}
边栏推荐
- 随手记01
- SimCLR:NLP中的对比学习
- Advance Computer Network Review(1)——FatTree
- 【每日一题】搬运工 (DFS / DP)
- Booking of tourism products in Gansu quadrupled: "green horse" became popular, and one room of B & B around Gansu museum was hard to find
- Niuke winter vacation training 6 maze 2
- Detailed explanation of dynamic planning
- Leetcode: Jianzhi offer 04 Search in two-dimensional array
- LeetCode:劍指 Offer 42. 連續子數組的最大和
- KDD 2022论文合集(持续更新中)
猜你喜欢

自定义卷积注意力算子的CUDA实现

I-BERT

Redis之五大基础数据结构深入、应用场景

Improved deep embedded clustering with local structure preservation (Idec)

Selenium+pytest automated test framework practice (Part 2)

Advanced Computer Network Review(4)——Congestion Control of MPTCP
![[OC]-<UI入门>--常用控件-UIButton](/img/4d/f5a62671068b26ef43f1101981c7bb.png)
[OC]-<UI入门>--常用控件-UIButton
![[OC foundation framework] - [set array]](/img/b5/5e49ab9d026c60816f90f0c47b2ad8.png)
[OC foundation framework] - [set array]

BN折叠及其量化

数字人主播618手语带货,便捷2780万名听障人士
随机推荐
MYSQL卸载方法与安装方法
How to intercept the string correctly (for example, intercepting the stock in operation by applying the error information)
Once you change the test steps, write all the code. Why not try yaml to realize data-driven?
[OC foundation framework] - string and date and time >
【shell脚本】——归档文件脚本
Leetcode刷题题解2.1.1
What is MySQL? What is the learning path of MySQL
Nacos 的安装与服务的注册
Computer graduation design PHP Zhiduo online learning platform
Leetcode: Jianzhi offer 04 Search in two-dimensional array
[OC-Foundation框架]--<Copy对象复制>
Intel distiller Toolkit - Quantitative implementation 1
LeetCode:124. Maximum path sum in binary tree
Parameterization of postman
注意力机制的一种卷积替代方式
多元聚类分析
LeetCode:41. 缺失的第一个正数
LeetCode:236. 二叉树的最近公共祖先
Mongodb installation and basic operation
LeetCode:221. 最大正方形