Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to get the client IP address through ctx like in the gin framework? #3756

Closed
imajinyun opened this issue Dec 4, 2023 · 4 comments
Closed

Comments

@imajinyun
Copy link

In the Gin framework, you can get the client IP using (ctx *gin.Context).ClientIP(). Is there a similar method to achieve this in ZeroMicro? Currently, getting it via ip, _, err := net.SplitHostPort(r.RemoteAddr) is a bit inconvenient.

@henryjhenry
Copy link

You can use httpx.GetRemoteAddr(*http.Request) in generated handler code.

@imajinyun
Copy link
Author

What if i want to use it in the service logic layer? Apart from passing parameters. thanks @aishuchen

@henryjhenry
Copy link

What if i want to use it in the service logic layer? Apart from passing parameters. thanks @aishuchen

  1. add ClientIP property in ServiceContext, and set it in handler
type ServiceContext struct {
    // ...
    ClientIP string
}

// handler
func YouHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
                svcCtx.ClientIP = httpx.GetRemoteAddr(r) // set in here
		l :=logic.NewLogic(r.Context(), svcCtx)
		err := l.Process(&req)
		if err != nil {
			httpx.ErrorCtx(r.Context(), w, err)
		} else {
			httpx.OkJsonCtx(r.Context(), w, nil)
		}
	}
}
  1. add ClientIP property in YouLogic
type YouLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
	ClientIP string
}

// handler
func YouHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		l :=logic.NewLogic(r.Context(), svcCtx)
                l.ClientIP = httpx.GetRemoteAddr(r) // set in here
		err := l.Process(&req)
		if err != nil {
			httpx.ErrorCtx(r.Context(), w, err)
		} else {
			httpx.OkJsonCtx(r.Context(), w, nil)
		}
	}
}
  1. use context
// handler
func YouHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
                clientIP := httpx.GetRemoteAddr(r)
                ctx := context.WithValue(r.Context(), "clientIP", clientIP) // set in here

		l :=logic.NewLogic(r.Context(), svcCtx)
		err := l.Process(&req)
		if err != nil {
			httpx.ErrorCtx(r.Context(), w, err)
		} else {
			httpx.OkJsonCtx(r.Context(), w, nil)
		}
	}
}

// method of YourLogic
func (l *YourLogic) Process(req *YouReq) error {
        clientIP := l.ctx.Value("clientIP") // get in here
}

And, use context in go-zero middleware, you can get client IP in all logics

@imajinyun
Copy link
Author

imajinyun commented Dec 7, 2023

Awesome @aishuchen, but i solved it this way:

  1. handler layer:
ctx := context.WithValue(r.Context(), "ip", httpx.GetRemoteAddr(r))
l := signin.NewXxxLogic(ctx, svcCtx)
  1. logic layer:
l.ctx.Value("ip").(string)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants