gin-gonic / gin

Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.
https://gin-gonic.com/
MIT License
76.96k stars 7.92k forks source link

Can't get ClientIP run in AWS Lambda with gin #3501

Open rts-gordon opened 1 year ago

rts-gordon commented 1 year ago

Description

Hi there, I run a gin web application in AWS Lambda, but I can't get the client IP with gin function: context.ClientIP() or context.RemoteIP(). Very appreciate for anyone's help.

Code

func getIP(c *gin.Context) string {
  return c.ClientIP()
  //return c.RemoteIP()
}

call getIP() and get empty.

Environment

radurobot commented 1 year ago

Do you have any trusted proxies set up?

rts-gordon commented 1 year ago

Hi @radurobot Thanks for your reply.

No, there are no any proxies set up. The gin application is lunched in AWS lambda and access the API via AWS API Gateway.

If the gin application run in VM or PC, the Client IP can be obtained.

Trygun commented 1 year ago

Perhaps accepting this will solve the problem: https://github.com/gin-gonic/gin/pull/3520 we have a similar problem

rts-gordon commented 1 year ago

Thanks for your message. Waiting for testing new function after merge into main branch.

jiqing112 commented 1 year ago

Perhaps accepting this will solve the problem: #3520

the problem have be solved ?

BranislavLazic commented 1 year ago

@Trygun I've seen your PR. Is there any way to bypass this issue with the current version of Gin?

duaneking commented 1 year ago

This is working for me in AWS just fine.

You just need to configure it correctly.

BranislavLazic commented 1 year ago

@duaneking If so, can you please elaborate, how? I've set X-Forwarded-For on API Gateway, but I obtain it through ctx.GetHeader call.

duaneking commented 1 year ago

that's because the getheader call is the wrong place to do it; its not working the way you want because that's the wrong place to configure it. Read the docs and the other bugs people have also filed after not reading the docs first.

To get you started: https://github.com/gin-gonic/gin/issues/3336

Close this bug once that helps you, please.

rts-gordon commented 1 year ago

Hi @duaneking Thanks for your response and docs. I read the issues carefully.

I add TrustedPlatform to my code:

    router := gin.New()
    router.SetTrustedProxies(nil)
    router.TrustedPlatform = "X-Forwarded-For"
        r1 := router.Group("/users")
    r1.POST("/login", ctl.login)

       ......another function......
       func (ctl *UserController) login(c *gin.Context) {
          log.Printf("client real IP:%s", c.ClientIP());
          ......
      }      
}

This code run in AWS Lambda. Unfortunately, it can't get the real client IP, did I do something wrong?

Thanks for your help.

duaneking commented 1 year ago

Its working for me correctly in production, and in the gin unit tests that pass before every release.

As this is also something that's a part of the unit tests that pass for every release, the burden of proof is on you.

If its not working for you then you need to check your entire config; if you configured the system you have deployed wrong, then you may need to use a different header or your sytem may be injecting the wrong ip. Thats a config issue, not a bug in gin.

duaneking commented 1 year ago

The code I have working in prod is effectively everything you have been given already:

gin.SetMode(gin.DebugMode)
router = gin.New()
router.SetTrustedProxies(nil)
router.TrustedPlatform = "X-Forwarded-For"

But remember, you need to read the AWS docs and configure the api gateway correctly as well. It honestly sounds to me like you have a misconfigured API gateway, so check that.