updated jwt

7/jwt
ajikamaludin 2 years ago
parent d55c1849eb
commit 0e7da77519
Signed by: ajikamaludin
GPG Key ID: 476C9A2B4B794EBB

@ -202,4 +202,51 @@ runtime.HTTPError = errors.CustomHTTPError
- implement logger for `pkg/v1/utils/errors/errors.go` to log any of error from our service
- implement logger for `router/http.go` to log response grpc rest api service
- `go run .`
- test call method callapi will generate hif log, custom-error generate error log, call rest will generate rest log
- test call method callapi will generate hif log, custom-error generate error log, call rest will generate rest log
### Jwt ( Json Web Tokens ) Auth
- add jwt configs to `config.yaml`, jwt: issuer: ajikamaludin, key: P@ssw0rd, type: Bearer
- changes `pkg/v1/config/config.go` add new config struct and validate config, [UPDATE] change New to GetInstance for singleton config
- changes `pkg/v1/utils/constants/constants.go` to add new const for jwt token expired and refresh token expired
- `go get github.com/dgrijalva/jwt-go`, lib to handle jwt token in go
- create new pkg `pkg/v1/jwt/jwt.go`, implement Generate token and Claim token
- create new proto `proto/v1/auth/auth.proto` auth for login and register service, recompile `sh compile-proto.sh` [UPDATE]
- implement `api/v1/auth/auth.go`, `api/v1/auth/login.go` and `api/v1/auth/register.go`
- register new grpc service to grpc server
```go
authpb.RegisterAuthServiceServer(grpcServer, auth.New(configs, logger))
```
- register new grp service to grpc gateay (http.go)
```go
authpb.RegisterAuthServiceHandler,
```
- implement middleware in grpc server, for check jwtoken in every request , and add
```go
grpcServer := grpc.NewServer(
grpc.UnaryInterceptor(
grpc_middleware.ChainUnaryServer(
authInterceptor,
),
),
)
```
- test call login with any userid and password
```bash
curl -X POST -d '{"userId":"aji","password":"pass"}' http://localhost:8080/api/v1/auth/login
```
- result
```json
{
"success":true,
"code":"0000",
"desc":"SUCCESS",
"auth":
{
"type":"Bearer",
"access":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWppIiwiZXhwIjoxNjU4MTU2Njk5LCJpc3MiOiJiYW5rcmF5YSJ9.5o3b0twKzuqVzPtS68GMD6pw91m4JbCaJrg57iQw06A",
"expiredPeriode":3600,
"refresh":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWppIiwiaXNSZWZyZXNoIjp0cnVlLCJleHAiOjE2NTgxNTY2OTksImlzcyI6ImJhbmtyYXlhIn0.C8ZF9JFYWJIg3A0f9Ax2kWlPd1LJPeKZtDOSjX_KW6E"
}
}
```
- use access token to access other resource / service - method

@ -0,0 +1,52 @@
package auth
import (
"github.com/ajikamaludin/go-grpc_basic/configs"
"github.com/ajikamaludin/go-grpc_basic/pkg/v1/utils/errors"
authpb "github.com/ajikamaludin/go-grpc_basic/proto/v1/auth"
"github.com/sirupsen/logrus"
"google.golang.org/grpc/codes"
)
// Method is the methode type
type Method int
const (
// SchemeCode of different Methods
GET Method = iota
REGISTER
LOGIN
)
type Server struct {
config *configs.Configs
logger *logrus.Logger
}
func New(config *configs.Configs, logger *logrus.Logger) *Server {
return &Server{
config: config,
logger: logger,
}
}
// isValidRequest validates the status request
func isValidRequest(m Method, req *authpb.Request) error {
switch m {
case REGISTER, LOGIN:
if req.GetUserId() == "" {
return errors.FormatError(codes.InvalidArgument, &errors.Response{
Code: "1000",
Msg: "userId is empty",
})
}
if req.GetPassword() == "" {
return errors.FormatError(codes.InvalidArgument, &errors.Response{
Code: "1000",
Msg: "password is empty",
})
}
}
return nil
}

@ -0,0 +1,45 @@
package auth
import (
"context"
"github.com/ajikamaludin/go-grpc_basic/pkg/v1/jwt"
"github.com/ajikamaludin/go-grpc_basic/pkg/v1/utils/constants"
"github.com/ajikamaludin/go-grpc_basic/pkg/v1/utils/errors"
authpb "github.com/ajikamaludin/go-grpc_basic/proto/v1/auth"
"google.golang.org/grpc/codes"
)
func (s *Server) Login(ctx context.Context, req *authpb.Request) (*authpb.Response, error) {
err := isValidRequest(LOGIN, req)
if err != nil {
s.logger.Errorf("[AUTH][LOGIN] ERROR %v", err)
return nil, err
}
// TODO: database logic to match user
auth, err := jwt.GenerateToken(s.config.Config, req.GetUserId())
if err != nil {
s.logger.Errorf("[AUTH][LOGIN] ERROR %v", err)
return nil, errors.FormatError(codes.Internal, &errors.Response{
Code: "1001",
Msg: err.Error(),
})
}
s.logger.Infof("[AUTH][LOGIN] SUCCESS")
return &authpb.Response{
Success: true,
Code: constants.SuccessCode,
Desc: constants.SuccesDesc,
Auth: &authpb.Auth{
Type: auth.Type,
Access: auth.Access,
ExpiredPeriode: int32(auth.ExpiredPeriode),
Refresh: auth.Refresh,
},
}, nil
}

@ -0,0 +1,19 @@
package auth
import (
"context"
"github.com/ajikamaludin/go-grpc_basic/pkg/v1/utils/constants"
authpb "github.com/ajikamaludin/go-grpc_basic/proto/v1/auth"
)
func (s *Server) Register(ctx context.Context, req *authpb.Request) (*authpb.Response, error) {
s.logger.Infof("[AUTH][REGISTER] SUCCESS")
return &authpb.Response{
Success: true,
Code: constants.SuccessCode,
Desc: constants.SuccesDesc,
}, nil
}

@ -13,3 +13,7 @@ postgres:
password: eta
cert:
path: certfile.pem
jwt:
issuer: ajikamaludin
key: P@ssw0rd
type: Bearer

@ -15,7 +15,7 @@ type Configs struct {
}
func New() (*Configs, *logrus.Logger, error) {
config, err := config.New()
config, err := config.GetInstance()
if err != nil {
return nil, nil, err

@ -30,8 +30,10 @@ require (
)
require (
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/golang/protobuf v1.5.2
github.com/gorilla/handlers v1.5.1
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb // indirect
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 // indirect

@ -14,6 +14,8 @@ github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWH
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
@ -25,6 +27,10 @@ github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0
github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@ -52,12 +58,18 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 h1:IPJ3dvxmJ4uczJe5YQdrYB16oTJlGSC/OyZDqUk9xX4=
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869/go.mod h1:cJ6Cj7dQo+O6GJNiMx+Pa94qKj+TG8ONdKHgMNIyyag=
github.com/jonboulle/clockwork v0.3.0 h1:9BSCMi8C+0qdApAp4auwX0RkLGUjs956h0EkuQymUhg=
github.com/jonboulle/clockwork v0.3.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570 h1:0iQektZGS248WXmGIYOwRXSQhD4qn3icjMpuxwO7qlo=
github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570/go.mod h1:BLt8L9ld7wVsvEWQbuLrUZnCMnUmLZ+CGDzKtclrTlE=
github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f h1:sgUSP4zdTUZYZgAGGtN5Lxk92rK+JUFOwf+FT99EEI4=
@ -66,36 +78,51 @@ github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 h1:Bvq8AziQ5j
github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042/go.mod h1:TPpsiPUEh0zFL1Snz4crhMlBe60PYxRHr5oFF3rRYg0=
github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs=
github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js=
github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tebeka/strftime v0.1.5 h1:1NQKN1NiQgkqd/2moD6ySP/5CoZQsKa1d3ZhJ44Jpmg=
github.com/tebeka/strftime v0.1.5/go.mod h1:29/OidkoWHdEKZqzyDLUyC+LmgDgdHo4WAFCDT7D/Ig=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb h1:eBmm0M9fYhWpKZLjQUUKka/LtIxf46G4fxeEz5KJr9U=
@ -106,11 +133,14 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8=
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -124,6 +154,11 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -131,6 +166,7 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
@ -138,6 +174,7 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w=

@ -1 +1 @@
logs/error_2022-07-15-16:00:00.log
logs/error_2022-07-18-20:00:00.log

@ -1 +1 @@
logs/hif_2022-07-15-17:00:00.log
logs/rest_2022-07-18-21:00:00.log

@ -6,6 +6,7 @@ import (
"fmt"
"log"
"os"
"sync"
"gopkg.in/yaml.v2"
)
@ -31,15 +32,36 @@ type Config struct {
Cert struct {
Path string `yaml:"path"`
} `yaml:"cert"`
Jwt struct {
Issuer string `yaml:"issuer"`
Key string `yaml:"key"`
Type string `yaml:"type"`
} `yaml:"jwt"`
}
func New() (*Config, error) {
var lock = &sync.Mutex{}
var config *Config
func GetInstance() (*Config, error) {
if config == nil {
lock.Lock()
defer lock.Unlock()
config, err := new()
if err != nil {
return nil, err
}
return config, nil
}
return config, nil
}
func new() (*Config, error) {
cfgPath, err := parseFlag()
if err != nil {
log.Fatal(err)
}
config := &Config{}
config = &Config{}
file, err := os.Open(cfgPath)
if err != nil {
@ -128,6 +150,15 @@ func validateConfigData(config *Config) error {
if config.Cert.Path == "" {
return errors.New("cert.path is empty")
}
if config.Jwt.Issuer == "" {
return errors.New("jwt.issuer is empty")
}
if config.Jwt.Key == "" {
return errors.New("jwt.key is empty")
}
if config.Jwt.Type == "" {
return errors.New("jwt.type is empty")
}
return nil
}

@ -0,0 +1,130 @@
package jwt
import (
"strings"
"time"
"github.com/ajikamaludin/go-grpc_basic/pkg/v1/utils/errors"
"github.com/ajikamaludin/go-grpc_basic/pkg/v1/config"
"github.com/ajikamaludin/go-grpc_basic/pkg/v1/utils/constants"
"github.com/dgrijalva/jwt-go"
)
type CustomClaims struct {
User string `json:"user,omitempty"`
IsRefresh bool `json:"isRefresh,omitempty"`
jwt.StandardClaims
}
type Token struct {
Type string
Access string
ExpiredPeriode int64
Refresh string
}
func GenerateToken(config *config.Config, user string) (*Token, error) {
atoken, err := set(user, false, constants.Jwt_Token_Expired_Periode, config)
if err != nil {
return nil, err
}
arefresh, err := set(user, true, constants.Jwt_Refresh_Expired_Periode, config)
if err != nil {
return nil, err
}
return &Token{
Type: config.Jwt.Type,
Access: atoken,
ExpiredPeriode: constants.Jwt_Token_Expired_Periode,
Refresh: arefresh,
}, nil
}
func set(user string, isrefresh bool, exp time.Duration, config *config.Config) (string, error) {
// create refresh token
claims := CustomClaims{
User: user,
IsRefresh: isrefresh,
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().Add(exp * time.Second).Unix(),
Issuer: config.Jwt.Issuer,
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
atoken, err := token.SignedString([]byte(config.Jwt.Key))
if err != nil {
return "", err
}
return atoken, nil
}
func ClaimToken(config *config.Config, auth string, isrefresh bool) (jwt.MapClaims, error) {
var token *jwt.Token
var err error
if !isrefresh {
// Bearer token as RFC 6750 standard
if strings.Split(auth, " ")[0] != config.Jwt.Type {
return nil, errors.New("Invalid token")
}
token, err = claim(auth, config.Jwt.Key, false)
if err != nil {
return nil, err
}
} else {
token, err = claim(auth, config.Jwt.Key, true)
if err != nil {
return nil, err
}
}
claims, ok := token.Claims.(jwt.MapClaims)
if !ok || !token.Valid {
return nil, errors.New("failed to claim token")
}
// validate issuer
if claims["iss"] != config.Jwt.Issuer {
return nil, errors.New("Invalid token")
}
// validate refresh token
if isrefresh {
if claims["IsRefresh"] == false {
return nil, errors.New("Invalid token")
}
} else {
if claims["IsRefresh"] == true {
return nil, errors.New("Invalid token")
}
}
return claims, nil
}
func claim(auth, key string, isrefresh bool) (*jwt.Token, error) {
if !isrefresh {
auth = strings.Split(auth, " ")[1]
}
token, err := jwt.Parse(auth, func(token *jwt.Token) (interface{}, error) {
if method, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
errors.New("Signing method invalid")
} else if method != jwt.SigningMethodHS256 {
errors.New("Signing method invalid")
}
return []byte(key), nil
})
if err != nil {
return nil, err
}
return token, nil
}

@ -30,3 +30,13 @@ const (
URLEncodedType = "application/x-www-form-urlencoded"
STREAMType = "application/octet-stream"
)
const (
Jwt_Refresh_Expired_Periode = 3600
Jwt_Token_Expired_Periode = 3600
)
const (
Endpoint_Auth_Register = `/api.gogrpc.v1.auth.AuthService/Register`
Endpoint_Auth_Login = `/api.gogrpc.v1.auth.AuthService/Login`
)

@ -1,7 +1,11 @@
#!/bin/bash
WORKDIR=github.com/ajikamaludin/go-grpc_basic
protoc \
set -ve
for x in $(ls v1)
do
protoc \
-I. \
-I/usr/local/include \
-I${GOPATH}/src \
@ -9,4 +13,6 @@ protoc \
-I${GOPATH}/src/$WORKDIR/proto/lib \
--go_out=plugins=grpc:$GOPATH/src \
--grpc-gateway_out=logtostderr=true:$GOPATH/src \
v1/*/*.proto
v1/$x/$x.proto
done

@ -0,0 +1,480 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.21.2
// source: v1/auth/auth.proto
package auth
import (
context "context"
_ "google.golang.org/genproto/googleapis/api/annotations"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type Request struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
UserId string `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"`
Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"`
}
func (x *Request) Reset() {
*x = Request{}
if protoimpl.UnsafeEnabled {
mi := &file_v1_auth_auth_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Request) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Request) ProtoMessage() {}
func (x *Request) ProtoReflect() protoreflect.Message {
mi := &file_v1_auth_auth_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Request.ProtoReflect.Descriptor instead.
func (*Request) Descriptor() ([]byte, []int) {
return file_v1_auth_auth_proto_rawDescGZIP(), []int{0}
}
func (x *Request) GetUserId() string {
if x != nil {
return x.UserId
}
return ""
}
func (x *Request) GetPassword() string {
if x != nil {
return x.Password
}
return ""
}
type Auth struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
Access string `protobuf:"bytes,2,opt,name=access,proto3" json:"access,omitempty"`
ExpiredPeriode int32 `protobuf:"varint,3,opt,name=expiredPeriode,proto3" json:"expiredPeriode,omitempty"`
Refresh string `protobuf:"bytes,4,opt,name=refresh,proto3" json:"refresh,omitempty"`
}
func (x *Auth) Reset() {
*x = Auth{}
if protoimpl.UnsafeEnabled {
mi := &file_v1_auth_auth_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Auth) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Auth) ProtoMessage() {}
func (x *Auth) ProtoReflect() protoreflect.Message {
mi := &file_v1_auth_auth_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Auth.ProtoReflect.Descriptor instead.
func (*Auth) Descriptor() ([]byte, []int) {
return file_v1_auth_auth_proto_rawDescGZIP(), []int{1}
}
func (x *Auth) GetType() string {
if x != nil {
return x.Type
}
return ""
}
func (x *Auth) GetAccess() string {
if x != nil {
return x.Access
}
return ""
}
func (x *Auth) GetExpiredPeriode() int32 {
if x != nil {
return x.ExpiredPeriode
}
return 0
}
func (x *Auth) GetRefresh() string {
if x != nil {
return x.Refresh
}
return ""
}
type Response struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"`
Code string `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"`
Desc string `protobuf:"bytes,3,opt,name=desc,proto3" json:"desc,omitempty"`
Auth *Auth `protobuf:"bytes,4,opt,name=auth,proto3" json:"auth,omitempty"`
}
func (x *Response) Reset() {
*x = Response{}
if protoimpl.UnsafeEnabled {
mi := &file_v1_auth_auth_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Response) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Response) ProtoMessage() {}
func (x *Response) ProtoReflect() protoreflect.Message {
mi := &file_v1_auth_auth_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Response.ProtoReflect.Descriptor instead.
func (*Response) Descriptor() ([]byte, []int) {
return file_v1_auth_auth_proto_rawDescGZIP(), []int{2}
}
func (x *Response) GetSuccess() bool {
if x != nil {
return x.Success
}
return false
}
func (x *Response) GetCode() string {
if x != nil {
return x.Code
}
return ""
}
func (x *Response) GetDesc() string {
if x != nil {
return x.Desc
}
return ""
}
func (x *Response) GetAuth() *Auth {
if x != nil {
return x.Auth
}
return nil
}
var File_v1_auth_auth_proto protoreflect.FileDescriptor
var file_v1_auth_auth_proto_rawDesc = []byte{
0x0a, 0x12, 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x61, 0x70, 0x69, 0x2e, 0x67, 0x6f, 0x67, 0x72, 0x70, 0x63,
0x2e, 0x76, 0x31, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3d, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73,
0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73,
0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x74, 0x0a, 0x04, 0x41, 0x75, 0x74, 0x68, 0x12, 0x12, 0x0a,
0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70,
0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x06, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x65, 0x78, 0x70,
0x69, 0x72, 0x65, 0x64, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
0x05, 0x52, 0x0e, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x64, 0x50, 0x65, 0x72, 0x69, 0x6f, 0x64,
0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01,
0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x22, 0x7a, 0x0a, 0x08, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65,
0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73,
0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x65, 0x73, 0x63, 0x18, 0x03, 0x20,
0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x65, 0x73, 0x63, 0x12, 0x2c, 0x0a, 0x04, 0x61, 0x75, 0x74,
0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x67, 0x6f,
0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x41, 0x75, 0x74,
0x68, 0x52, 0x04, 0x61, 0x75, 0x74, 0x68, 0x32, 0xd9, 0x01, 0x0a, 0x0b, 0x41, 0x75, 0x74, 0x68,
0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x61, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e,
0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x67, 0x6f, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31,
0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x67, 0x6f, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x61, 0x75,
0x74, 0x68, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d, 0x82, 0xd3, 0xe4,
0x93, 0x02, 0x17, 0x22, 0x12, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74,
0x68, 0x2f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x3a, 0x01, 0x2a, 0x12, 0x67, 0x0a, 0x08, 0x52, 0x65,
0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x67, 0x6f, 0x67,
0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x67, 0x6f, 0x67, 0x72, 0x70, 0x63,
0x2e, 0x76, 0x31, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x22, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f,
0x76, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72,
0x3a, 0x01, 0x2a, 0x42, 0x35, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
0x6d, 0x2f, 0x61, 0x6a, 0x69, 0x6b, 0x61, 0x6d, 0x61, 0x6c, 0x75, 0x64, 0x69, 0x6e, 0x2f, 0x67,
0x6f, 0x2d, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x2f, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
}
var (
file_v1_auth_auth_proto_rawDescOnce sync.Once
file_v1_auth_auth_proto_rawDescData = file_v1_auth_auth_proto_rawDesc
)
func file_v1_auth_auth_proto_rawDescGZIP() []byte {
file_v1_auth_auth_proto_rawDescOnce.Do(func() {
file_v1_auth_auth_proto_rawDescData = protoimpl.X.CompressGZIP(file_v1_auth_auth_proto_rawDescData)
})
return file_v1_auth_auth_proto_rawDescData
}
var file_v1_auth_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_v1_auth_auth_proto_goTypes = []interface{}{
(*Request)(nil), // 0: api.gogrpc.v1.auth.Request
(*Auth)(nil), // 1: api.gogrpc.v1.auth.Auth
(*Response)(nil), // 2: api.gogrpc.v1.auth.Response
}
var file_v1_auth_auth_proto_depIdxs = []int32{
1, // 0: api.gogrpc.v1.auth.Response.auth:type_name -> api.gogrpc.v1.auth.Auth
0, // 1: api.gogrpc.v1.auth.AuthService.Login:input_type -> api.gogrpc.v1.auth.Request
0, // 2: api.gogrpc.v1.auth.AuthService.Register:input_type -> api.gogrpc.v1.auth.Request
2, // 3: api.gogrpc.v1.auth.AuthService.Login:output_type -> api.gogrpc.v1.auth.Response
2, // 4: api.gogrpc.v1.auth.AuthService.Register:output_type -> api.gogrpc.v1.auth.Response
3, // [3:5] is the sub-list for method output_type
1, // [1:3] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_v1_auth_auth_proto_init() }
func file_v1_auth_auth_proto_init() {
if File_v1_auth_auth_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_v1_auth_auth_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Request); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_v1_auth_auth_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Auth); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_v1_auth_auth_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Response); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_v1_auth_auth_proto_rawDesc,
NumEnums: 0,
NumMessages: 3,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_v1_auth_auth_proto_goTypes,
DependencyIndexes: file_v1_auth_auth_proto_depIdxs,
MessageInfos: file_v1_auth_auth_proto_msgTypes,
}.Build()
File_v1_auth_auth_proto = out.File
file_v1_auth_auth_proto_rawDesc = nil
file_v1_auth_auth_proto_goTypes = nil
file_v1_auth_auth_proto_depIdxs = nil
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConnInterface
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion6
// AuthServiceClient is the client API for AuthService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type AuthServiceClient interface {
Login(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error)
Register(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error)
}
type authServiceClient struct {
cc grpc.ClientConnInterface
}
func NewAuthServiceClient(cc grpc.ClientConnInterface) AuthServiceClient {
return &authServiceClient{cc}
}
func (c *authServiceClient) Login(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) {
out := new(Response)
err := c.cc.Invoke(ctx, "/api.gogrpc.v1.auth.AuthService/Login", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *authServiceClient) Register(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) {
out := new(Response)
err := c.cc.Invoke(ctx, "/api.gogrpc.v1.auth.AuthService/Register", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// AuthServiceServer is the server API for AuthService service.
type AuthServiceServer interface {
Login(context.Context, *Request) (*Response, error)
Register(context.Context, *Request) (*Response, error)
}
// UnimplementedAuthServiceServer can be embedded to have forward compatible implementations.
type UnimplementedAuthServiceServer struct {
}
func (*UnimplementedAuthServiceServer) Login(context.Context, *Request) (*Response, error) {
return nil, status.Errorf(codes.Unimplemented, "method Login not implemented")
}
func (*UnimplementedAuthServiceServer) Register(context.Context, *Request) (*Response, error) {
return nil, status.Errorf(codes.Unimplemented, "method Register not implemented")
}
func RegisterAuthServiceServer(s *grpc.Server, srv AuthServiceServer) {
s.RegisterService(&_AuthService_serviceDesc, srv)
}
func _AuthService_Login_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(Request)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AuthServiceServer).Login(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/api.gogrpc.v1.auth.AuthService/Login",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AuthServiceServer).Login(ctx, req.(*Request))
}
return interceptor(ctx, in, info, handler)
}
func _AuthService_Register_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(Request)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AuthServiceServer).Register(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/api.gogrpc.v1.auth.AuthService/Register",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AuthServiceServer).Register(ctx, req.(*Request))
}
return interceptor(ctx, in, info, handler)
}
var _AuthService_serviceDesc = grpc.ServiceDesc{
ServiceName: "api.gogrpc.v1.auth.AuthService",
HandlerType: (*AuthServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Login",
Handler: _AuthService_Login_Handler,
},
{
MethodName: "Register",
Handler: _AuthService_Register_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "v1/auth/auth.proto",
}

@ -0,0 +1,250 @@
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: v1/auth/auth.proto
/*
Package auth is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package auth
import (
"context"
"io"
"net/http"
"github.com/golang/protobuf/descriptor"
"github.com/golang/protobuf/proto"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/grpc-ecosystem/grpc-gateway/utilities"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
)
// Suppress "imported and not used" errors
var _ codes.Code
var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
var _ = descriptor.ForMessage
var _ = metadata.Join
func request_AuthService_Login_0(ctx context.Context, marshaler runtime.Marshaler, client AuthServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq Request
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.Login(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_AuthService_Login_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq Request
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.Login(ctx, &protoReq)
return msg, metadata, err
}
func request_AuthService_Register_0(ctx context.Context, marshaler runtime.Marshaler, client AuthServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq Request
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.Register(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_AuthService_Register_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq Request
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.Register(ctx, &protoReq)
return msg, metadata, err
}
// RegisterAuthServiceHandlerServer registers the http handlers for service AuthService to "mux".
// UnaryRPC :call AuthServiceServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterAuthServiceHandlerFromEndpoint instead.
func RegisterAuthServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server AuthServiceServer) error {
mux.Handle("POST", pattern_AuthService_Login_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_AuthService_Login_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_AuthService_Login_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("POST", pattern_AuthService_Register_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_AuthService_Register_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_AuthService_Register_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
// RegisterAuthServiceHandlerFromEndpoint is same as RegisterAuthServiceHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterAuthServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
conn, err := grpc.Dial(endpoint, opts...)
if err != nil {
return err
}
defer func() {
if err != nil {
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
return
}
go func() {
<-ctx.Done()
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
}()
}()
return RegisterAuthServiceHandler(ctx, mux, conn)
}
// RegisterAuthServiceHandler registers the http handlers for service AuthService to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterAuthServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
return RegisterAuthServiceHandlerClient(ctx, mux, NewAuthServiceClient(conn))
}
// RegisterAuthServiceHandlerClient registers the http handlers for service AuthService
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "AuthServiceClient".
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "AuthServiceClient"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
// "AuthServiceClient" to call the correct interceptors.
func RegisterAuthServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client AuthServiceClient) error {
mux.Handle("POST", pattern_AuthService_Login_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_AuthService_Login_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_AuthService_Login_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("POST", pattern_AuthService_Register_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_AuthService_Register_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_AuthService_Register_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_AuthService_Login_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "auth", "login"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_AuthService_Register_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "auth", "register"}, "", runtime.AssumeColonVerbOpt(true)))
)
var (
forward_AuthService_Login_0 = runtime.ForwardResponseMessage
forward_AuthService_Register_0 = runtime.ForwardResponseMessage
)

@ -0,0 +1,42 @@
syntax = "proto3";
package api.gogrpc.v1.auth;
option go_package = "github.com/ajikamaludin/go-grpc_basic/proto/v1/auth";
import "google/api/annotations.proto";
message Request {
string userId = 1;
string password = 2;
}
message Auth {
string type = 1;
string access = 2;
int32 expiredPeriode = 3;
string refresh = 4;
}
message Response {
bool success = 1;
string code = 2;
string desc = 3;
Auth auth = 4;
}
service AuthService {
rpc Login(Request) returns (Response) {
option (google.api.http) = {
post: "/api/v1/auth/login",
body:"*"
};
}
rpc Register(Request) returns (Response) {
option (google.api.http) = {
post: "/api/v1/auth/register",
body:"*"
};
}
}

@ -1,15 +1,28 @@
package router
import (
"context"
"fmt"
"log"
"net"
"strconv"
"github.com/ajikamaludin/go-grpc_basic/api/v1/auth"
"github.com/ajikamaludin/go-grpc_basic/api/v1/health"
"github.com/ajikamaludin/go-grpc_basic/configs"
"github.com/ajikamaludin/go-grpc_basic/pkg/v1/config"
"github.com/ajikamaludin/go-grpc_basic/pkg/v1/jwt"
"github.com/ajikamaludin/go-grpc_basic/pkg/v1/utils/constants"
"github.com/ajikamaludin/go-grpc_basic/pkg/v1/utils/errors"
"github.com/ajikamaludin/go-grpc_basic/pkg/v1/utils/logger"
authpb "github.com/ajikamaludin/go-grpc_basic/proto/v1/auth"
hlpb "github.com/ajikamaludin/go-grpc_basic/proto/v1/health"
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/sirupsen/logrus"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/reflection"
)
@ -20,9 +33,18 @@ func NewGRPCServer(configs *configs.Configs, logger *logrus.Logger) error {
}
// register grpc service server
grpcServer := grpc.NewServer()
// grpcServer := grpc.NewServer()
grpcServer := grpc.NewServer(
grpc.UnaryInterceptor(
grpc_middleware.ChainUnaryServer(
authInterceptor,
),
),
)
hlpb.RegisterHealthServiceServer(grpcServer, health.New(configs, logger))
authpb.RegisterAuthServiceServer(grpcServer, auth.New(configs, logger))
// add reflection service
reflection.Register(grpcServer)
@ -34,3 +56,52 @@ func NewGRPCServer(configs *configs.Configs, logger *logrus.Logger) error {
return nil
}
func authInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
fmt.Println(info)
if !(info.FullMethod == constants.Endpoint_Auth_Login ||
info.FullMethod == constants.Endpoint_Auth_Register) {
// var userId string
// // create config and logger
// config, err := config.New()
// if err != nil {
// return nil, err
// }
// read header from incoming request
headers, ok := metadata.FromIncomingContext(ctx)
if !ok {
return nil, errors.New("error get context")
}
if len(headers.Get("Authorization")) < 1 || headers.Get("Authorization")[0] == "" {
return nil, errors.FormatError(codes.InvalidArgument, &errors.Response{
Code: "1000",
Msg: "header Authorization is empty",
})
}
config, err := config.GetInstance()
if err != nil {
return nil, err
}
//Verifying token
_, err = jwt.ClaimToken(config, headers.Get("Authorization")[0], false)
if err != nil {
return nil, errors.FormatError(codes.Unauthenticated, &errors.Response{
Code: strconv.Itoa(runtime.HTTPStatusFromCode(codes.Unauthenticated)),
Msg: err.Error(),
})
}
}
// store request log
err := logger.StoreRestRequest(ctx, req, info, "")
if err != nil {
return nil, err
}
return handler(ctx, req)
}

@ -17,6 +17,7 @@ import (
"github.com/golang/protobuf/proto"
authpb "github.com/ajikamaludin/go-grpc_basic/proto/v1/auth"
hlpb "github.com/ajikamaludin/go-grpc_basic/proto/v1/health"
)
@ -42,6 +43,7 @@ func NewHTTPServer(configs *configs.Configs, loggger *logrus.Logger) error {
for _, f := range []func(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error{
// register grpc service handler
hlpb.RegisterHealthServiceHandler,
authpb.RegisterAuthServiceHandler,
} {
if err = f(ctx, rmux, conn); err != nil {
return err

Loading…
Cancel
Save