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

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

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

No branches or pull requests

3 participants