Skip to content
New issue

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

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

Already on GitHub? # to your account

Integrating with Gin #4

Open
dstroot opened this issue Dec 17, 2016 · 11 comments
Open

Integrating with Gin #4

dstroot opened this issue Dec 17, 2016 · 11 comments
Labels

Comments

@dstroot
Copy link

dstroot commented Dec 17, 2016

Anyone tried integrating this with Gin? Would something like this work?

	// Create the router
	r = gin.Default()

       auth := restgate.New("X-Auth-Key", "X-Auth-Secret", restgate.Static, restgate.Config{Context: C, Key: []string{"12345"}, Secret: []string{"secret"}}))

        // Create Gin middleware - integrate unrolled secure with Gin
	authMiddleware := func() gin.HandlerFunc {
		return func(c *gin.Context) {
			err := auth.Process(c.Writer, c.Request)
			// check(err)

			// Avoid header rewrite if response is a redirection.
			if status := c.Writer.Status(); status > 300 && status < 399 {
				c.Abort()
			}
		}
	}()

	// use the new security middleware
	r.Use(authMiddleware)
@pjebs
Copy link
Owner

pjebs commented Dec 18, 2016

Hi @dstroot.
Your code won't work but it's not hard to adapt it to work with Gin: https://github.com/gin-gonic/gin#custom-middleware

You are definitely on the right track though.
I believe you'll have to somehow get gin to call: func (self *RESTGate) ServeHTTP(w http.ResponseWriter, req *http.Request, next http.HandlerFunc)

@pjebs
Copy link
Owner

pjebs commented Dec 18, 2016

rg := restgate.New("X-Auth-Key", "X-Auth-Secret", restgate.Static, restgate.Config{Context: C, Key: []string{"12345"}, Secret: []string{"secret"}}))

rgAdapter := func(c *gin.Context) {

	nextAdapter := func(http.ResponseWriter, *http.Request) {
		c.Next()
	}

	rg.ServeHTTP(c.Writer, c.Request, nextAdapter)

}

r.Use(rgAdapter)

@pjebs pjebs added the question label Dec 18, 2016
@dstroot
Copy link
Author

dstroot commented Dec 18, 2016

Awesome! This compiles and runs (I am getting output from Restgate). Now I am looking to see if there is a development config setting that will not require HTTPS in development. Thoughts?

{"code":"3","error":"Please use HTTPS connection"}{"taxProApi":"/v1/:year/taxpro/:efin"}

This code works!

        // Initialize Restgate
        rg := restgate.New("X-Auth-Key", "X-Auth-Secret", restgate.Static, restgate.Config{Key: []string{"12345"}, Secret: []string{"secret"}})

	// Create Gin middleware - integrate Restgate with Gin
	rgAdapter := func(c *gin.Context) {
		nextAdapter := func(http.ResponseWriter, *http.Request) {
			c.Next()
		}
		rg.ServeHTTP(c.Writer, c.Request, nextAdapter)
	}

	// Use Restgate with Gin
	r.Use(rgAdapter)

@dstroot
Copy link
Author

dstroot commented Dec 18, 2016

Sorry - I found it.

	rg := restgate.New("X-Auth-Key", "X-Auth-Secret", restgate.Static, restgate.Config{
		Key:                []string{"12345"},
		Secret:             []string{"secret"},
		HTTPSProtectionOff: true,
	})

@pjebs pjebs changed the title Stab at integrating with Gin? Integrating with Gin Dec 18, 2016
@pjebs
Copy link
Owner

pjebs commented Dec 19, 2016

When restgate fails to validate, it should not write any more to the ResponseWriter.
{"code":"3","error":"Please use HTTPS connection"}{"taxProApi":"/v1/:year/taxpro/:efin"}

Something is not right there: You will have to call Abort or AbortWithError

rgAdapter := func(c *gin.Context) {
	nextCalled := false
	nextAdapter := func(http.ResponseWriter, *http.Request) {
		nextCalled = true
		c.Next()
	}
	rg.ServeHTTP(c.Writer, c.Request, nextAdapter)
	if nextCalled == false {
		c.AbortWithStatus(401)
	}
}

@pjebs
Copy link
Owner

pjebs commented Jan 4, 2017

       r = gin.Default()

        // Initialize Restgate
        rg := restgate.New("X-Auth-Key", "X-Auth-Secret", restgate.Static, restgate.Config{Key: []string{"12345"}, Secret: []string{"secret"}})

	// Create Gin middleware - integrate Restgate with Gin
	rgAdapter := func(c *gin.Context) {
		nextCalled := false
		nextAdapter := func(http.ResponseWriter, *http.Request) {
			nextCalled = true
			c.Next()
		}
		rg.ServeHTTP(c.Writer, c.Request, nextAdapter)
		if nextCalled == false {
			c.AbortWithStatus(401)
		}
	}

	// Use Restgate with Gin
	r.Use(rgAdapter)

@ThinkCats
Copy link

I want to redirect to some 401 page rather than the code:

{
  "code": "2",
  "error": "Unauthorized Access"
}

in the gin.

What should I do like this ?

@ThinkCats
Copy link

ThinkCats commented Mar 12, 2017

I tried :

if nextCalled == false {
			c.Redirect(401, "/401")
		}

But the error msg is the same as before:

{
 "code": "2",
 "error": "Unauthorized Access"
}

@pjebs

@pjebs
Copy link
Owner

pjebs commented Mar 12, 2017

The issue is the package was designed for making APIs. Redirects are unusual for a API response.
You will have to fork the package. The reason is because rg.ServeHTTP(c.Writer, c.Request, nextAdapter) already writes to the http.ResponseWriter. Therefore c.Redirect( ) won't be able to unambiguously indicate a redirect.

@pjebs
Copy link
Owner

pjebs commented Mar 12, 2017

Alternatively,
What you can do is create your own http.ResponseWriter and feed that into rg.ServeHTTP(OWNRESPONSEWRITER, c.Request, nextAdapter)

Then:

if nextCalled == false {
	c.Abort( )
	c.Redirect(401, "/401")
} else {
	//Copy OWNRESPONSEWRITER to ACTUAL RESPONSEWRITER
	//In practice, ignore this else clause and DO NOTHING.
}

You can use the ResponseRecorder from the net/http/httptest package if you want. It's probably easier to just create a skeleton ResponseWriter however (which would use up less memory).

@ThinkCats
Copy link

Ok, thank you very much ! @pjebs

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

No branches or pull requests

3 participants