GithubHelp home page GithubHelp logo

Comments (30)

Chris533 avatar Chris533 commented on July 19, 2024 1

Savsgio, thanks for your help, I will go to sleep first and contact later.

from atreugo.

Chris533 avatar Chris533 commented on July 19, 2024 1

I appreciate everything you do.

After the fix I will submit the cross-domain middleware pull request.

Have a nice day Savsgio! 🌞

from atreugo.

savsgio avatar savsgio commented on July 19, 2024

Hi @Chris533 ,

Could you explain more your error? please.

Do you need a CORS middleware, right?

from atreugo.

Chris533 avatar Chris533 commented on July 19, 2024

@savsgio
Yes, a atreugo CORS middleware or Header.set like

        ctx.Response.Header.Set("Access-Control-Allow-Credentials", corsAllowCredentials)
        ctx.Response.Header.Set("Access-Control-Allow-Headers", corsAllowHeaders)
        ctx.Response.Header.Set("Access-Control-Allow-Methods", corsAllowMethods)
        ctx.Response.Header.Set("Access-Control-Allow-Origin", corsAllowOrigin)

I'm using jwt_auth(like) middleware, Only postman working correct

server.go

package service
	server := atreugo.New(atConfig)

	// Register authentication middleware at first of all
	server.UseBefore(middleware)

	// Register auth routes
	auth.Api(server, db)

	// Run
	if err := server.ListenAndServe(); err != nil {
		panic(err)
	}

api.go

package auth
...
func Api(server *atreugo.Atreugo, db *pg.DB) {

	server.GET(auth_route.Me, func(ctx *atreugo.RequestCtx) error {
		return auth_controller.Me(ctx)
	})

	server.POST(auth_route.Login, func(ctx *atreugo.RequestCtx) error {
		return auth_controller.Login(ctx, db)
	})
...

Chrome Console Errors

Access to fetch at 'http://192.168.3.2:3000/api/v1/auth/login' from origin 'http://192.168.3.2:8000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Chrome Request Headers Errors

Provisional headers are shown

from atreugo.

savsgio avatar savsgio commented on July 19, 2024

I understand that you are not setting any CORS header now, right?

from atreugo.

Chris533 avatar Chris533 commented on July 19, 2024

Yes

from atreugo.

Chris533 avatar Chris533 commented on July 19, 2024

Tried setting CORS header in UseBefore(...), or server.method(...) not working

from atreugo.

savsgio avatar savsgio commented on July 19, 2024

Ok, you could create a before middleware to set the headers while i create the middleware into atreugo.

server.UseBefore(func(ctx *atreugo.RequestCtx) error {
	// Dinamyc value
	corsAllowOrigin := string(ctx.URI().Scheme()) + "://" + string(ctx.Host())
	// or static value
	corsAllowOrigin = "http://example.com"

	// Mandatory header
	ctx.Response.Header.Set("Access-Control-Allow-Origin", corsAllowOrigin)

	// Optional headers
	ctx.Response.Header.Set("Access-Control-Allow-Credentials", corsAllowCredentials)
	ctx.Response.Header.Set("Access-Control-Allow-Headers", corsAllowHeaders)
	ctx.Response.Header.Set("Access-Control-Allow-Methods", corsAllowMethods)

	return ctx.Next()
})

from atreugo.

savsgio avatar savsgio commented on July 19, 2024

I keep the issue to create the middleware or if you want, you could make a PR to add it.

I will have the pleasure to review it.

from atreugo.

Chris533 avatar Chris533 commented on July 19, 2024

Thanks

I test server.UseBefore in my code, not working, What am i doing wrong?

	server := atreugo.New(atConfig)

	// Register authentication middleware at first of all

	server.UseBefore(func(ctx *atreugo.RequestCtx) error {
		// Dinamyc value
		corsAllowOrigin := string(ctx.URI().Scheme()) + "://" + string(ctx.Host())
		// or static value
		corsAllowOrigin = "http://example.com"

		// Mandatory header
		ctx.Response.Header.Set("Access-Control-Allow-Origin", corsAllowOrigin)

		// Optional headers
		ctx.Response.Header.Set("Access-Control-Allow-Credentials", corsAllowCredentials)
		ctx.Response.Header.Set("Access-Control-Allow-Headers", corsAllowHeaders)
		ctx.Response.Header.Set("Access-Control-Allow-Methods", corsAllowMethods)

		return ctx.Next()
	})

	// Register auth routes
	auth.Api(server, db)

	// Run
	if err := server.ListenAndServe(); err != nil {
		panic(err)
	}

Same Chrome Errors

from atreugo.

Chris533 avatar Chris533 commented on July 19, 2024

In Postman, Headers has Access-Control-Allow-Origin,
In Chrome, Headers No 'Access-Control-Allow-Origin'
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

from atreugo.

Chris533 avatar Chris533 commented on July 19, 2024

Does fasthttp CORS limiting done before atreugo middleware ? So we need to use fasthttp.RequestHandler ?

from atreugo.

Chris533 avatar Chris533 commented on July 19, 2024

I also tried like this, CORS working, Chrome woring, but atreugo routes not working

forked atreugo.go

func (s *Atreugo) ListenAndServe(handler fasthttp.RequestHandler) error {
	s.server.Handler = handler
	ln, err := s.getListener()
	if err != nil {
		return err
	}

	if s.cfg.GracefulShutdown {
		return s.ServeGracefully(ln)
	}

	return s.Serve(ln)
}

my code server.go

func Server(db *pg.DB) {
...
	// Register authentication middleware at first of all
	server.UseBefore(middleware)

	// Register auth routes
	auth.Api(server, db)

	handler := cors.Default().Handler(requestHandler)

	// Run
	if err := server.ListenAndServe(handler); err != nil {
		panic(err)
	}
...
}

func requestHandler(ctx *fasthttp.RequestCtx) {
	ctx.SetContentType("application/json")
	fmt.Fprintf(ctx, "{\"hello\": \"world\"}")
}

from atreugo.

savsgio avatar savsgio commented on July 19, 2024

You are overriding atreugo handler s.server.Handler = handler, so it's a bad option, because all configurations in atreugo will not works

from atreugo.

savsgio avatar savsgio commented on July 19, 2024

So could you check which headers are setted in response?

from atreugo.

Chris533 avatar Chris533 commented on July 19, 2024

Yes, I checked, not setted in Chrome

from atreugo.

Chris533 avatar Chris533 commented on July 19, 2024

Have you used to make requests from different domains / or ports before, is it working?

from atreugo.

Chris533 avatar Chris533 commented on July 19, 2024

Does fasthttp CORS limiting done before atreugo middleware ? So we need to use fasthttp.RequestHandler ?

Could it be this the reason? 😊

from atreugo.

savsgio avatar savsgio commented on July 19, 2024

Does fasthttp CORS limiting done before atreugo middleware ? So we need to use fasthttp.RequestHandler ?

Could it be this the reason? 😊

I don't believe, because CORS is limited by the browser not by server
fasthttp.RequestHandler is a native fasthttp handler to manage request only, atreugo and others frameworks/routers use it

from atreugo.

savsgio avatar savsgio commented on July 19, 2024

This example works to me:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Page Title</title>
  </head>
  <body></body>

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  <script>
    $.ajax({ method: "GET", url: "http://0.0.0.0:8000" }).done(resp => {
      console.log(resp);
    });
  </script>
</html>
package main

import (
	"github.com/savsgio/atreugo/v10"
)

func main() {
	config := atreugo.Config{
		Addr: "0.0.0.0:8000",
	}
	server := atreugo.New(config)

	server.UseBefore(func(ctx *atreugo.RequestCtx) error {
		ctx.Response.Header.Set("Access-Control-Allow-Origin", "*")

		return ctx.Next()
	})

	server.GET("/", func(ctx *atreugo.RequestCtx) error {
		return ctx.TextResponse("Hello World")
	})

	if err := server.ListenAndServe(); err != nil {
		panic(err)
	}
}

from atreugo.

savsgio avatar savsgio commented on July 19, 2024

Do you use some plugin in your browser?

Because with this code

server.UseBefore(func(ctx *atreugo.RequestCtx) error {
	ctx.Response.Header.Set("Access-Control-Allow-Origin", "*")

	return ctx.Next()
})

The ajax request should works
Check in Debug console > Network in Chrome, the header Access-Control-Allow-Origin is setted on response,

from atreugo.

savsgio avatar savsgio commented on July 19, 2024

Are you make the request directly to the server? Or is there a proxy in the middle?

from atreugo.

Chris533 avatar Chris533 commented on July 19, 2024

Thanks, jq code working in Chrome with localhost.
I'm testing in IP address

from atreugo.

Chris533 avatar Chris533 commented on July 19, 2024

GET, POST (not json) working
POST json same errors too

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <title>Page Title</title>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body></body>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
  $.ajax({
    headers: {
      'Content-Type': 'application/json'
    },
    method: "POST",
    url: "http://0.0.0.0:8000" })
    .done(resp => {
      console.log(resp);
    });
</script>
</html>

package main

import (
	"github.com/savsgio/atreugo/v10"
)

func main() {
	config := &atreugo.Config{
		Addr: "0.0.0.0:8000",
	}
	server := atreugo.New(config)

	server.UseBefore(func(ctx *atreugo.RequestCtx) error {
		ctx.Response.Header.Set("Access-Control-Allow-Origin", "*")
		ctx.Response.Header.Set("Access-Control-Allow-Headers", "*")
		ctx.Response.Header.Set("Access-Control-Allow-Methods", "*")
		ctx.Response.Header.Set("Content-Type", "application/json;charset=utf-8")

		return ctx.Next()
	})

	server.POST("/", func(ctx *atreugo.RequestCtx) error {
		return ctx.TextResponse("Hello World")
	})

	if err := server.ListenAndServe(); err != nil {
		panic(err)
	}
}

from atreugo.

Chris533 avatar Chris533 commented on July 19, 2024

Hi Savagio, I make the request directly to the local PC without proxy,

POST json not working,

I tried with my code above again, could you test it please? #69 (comment)

from atreugo.

Chris533 avatar Chris533 commented on July 19, 2024

The CORS error was caused by the Preflight request,

When POST json:

    headers: {
      'Content-Type': 'application/json'
    },

it sends the OPTIONS request first, then POST request ,

so I added OPTIONS to solve that

	server.OPTIONS("/api/v1/auth/login", func(ctx *atreugo.RequestCtx) error {
		return ctx.Next()
	})
all example code:
package main

import (
	"github.com/savsgio/atreugo/v10"
)

var (
	corsAllowHeaders     = "Content-Type, authorization"
	corsAllowMethods     = "HEAD,GET,POST,PUT,DELETE,OPTIONS"
	corsAllowOrigin      = "*"
	corsAllowCredentials = "true"
)

func main() {
	config := &atreugo.Config{
		Addr: "0.0.0.0:8000",
	}
	server := atreugo.New(config)

	server.UseBefore(func(ctx *atreugo.RequestCtx) error {
		ctx.Response.Header.Set("Access-Control-Allow-Credentials", corsAllowCredentials)
		ctx.Response.Header.Set("Access-Control-Allow-Headers", corsAllowHeaders)
		ctx.Response.Header.Set("Access-Control-Allow-Methods", corsAllowMethods)
		ctx.Response.Header.Set("Access-Control-Allow-Origin", corsAllowOrigin)

		return ctx.Next()
	})

	server.OPTIONS("/api/v1/auth/login", func(ctx *atreugo.RequestCtx) error {
		return ctx.Next()
	})

	server.POST("/api/v1/auth/login", func(ctx *atreugo.RequestCtx) error {
		return ctx.TextResponse("Hello World")
	})

	if err := server.ListenAndServe(); err != nil {
		panic(err)
	}
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <title>Page Title</title>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body></body>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
  $.ajax({
    headers: {
      'Content-Type': 'application/json'
    },
    method: "POST",
    url: "http://192.168.3.2:8000/api/v1/auth/login" })
    .done(resp => {
      console.log(resp);
    });
</script>
</html>

By the way, I also tested with the fasthttprouter, only set POST route, no OPTIONS needed,
I'm confused for this reason, is it because of fasthttp.RequestHandler being overwritten by atreugo?

example code with fasthttprouter:
package main

import (
	"fmt"
	"github.com/buaazp/fasthttprouter"
	"github.com/savsgio/atreugo/v10"
	"github.com/valyala/fasthttp"
	"log"
)

var (
	corsAllowHeaders     = "Content-Type, authorization"
	corsAllowMethods     = "HEAD,GET,POST,PUT,DELETE,OPTIONS"
	corsAllowOrigin      = "*"
	corsAllowCredentials = "true"
)

func main0() {
	config := &atreugo.Config{
		Addr: "0.0.0.0:8000",
	}
	server := atreugo.New(config)

	server.UseBefore(func(ctx *atreugo.RequestCtx) error {
		ctx.Response.Header.Set("Access-Control-Allow-Credentials", corsAllowCredentials)
		ctx.Response.Header.Set("Access-Control-Allow-Headers", corsAllowHeaders)
		ctx.Response.Header.Set("Access-Control-Allow-Methods", corsAllowMethods)
		ctx.Response.Header.Set("Access-Control-Allow-Origin", corsAllowOrigin)

		return ctx.Next()
	})

	server.OPTIONS("/api/v1/auth/login", func(ctx *atreugo.RequestCtx) error {
		return ctx.Next()
	})

	server.POST("/api/v1/auth/login", func(ctx *atreugo.RequestCtx) error {
		return ctx.TextResponse("Hello World")
	})

	if err := server.ListenAndServe(); err != nil {
		panic(err)
	}
}

func CORS(next fasthttp.RequestHandler) fasthttp.RequestHandler {
	return func(ctx *fasthttp.RequestCtx) {

		ctx.Response.Header.Set("Access-Control-Allow-Credentials", corsAllowCredentials)
		ctx.Response.Header.Set("Access-Control-Allow-Headers", corsAllowHeaders)
		ctx.Response.Header.Set("Access-Control-Allow-Methods", corsAllowMethods)
		ctx.Response.Header.Set("Access-Control-Allow-Origin", corsAllowOrigin)

		next(ctx)
	}
}

func Index(ctx *fasthttp.RequestCtx) {
	fmt.Fprint(ctx, "fasthttprouter hello world")
}

func main() {
	router := fasthttprouter.New()
	router.POST("/api/v1/auth/login", Index)

	if err := fasthttp.ListenAndServe(":8000", CORS(router.Handler)); err != nil {
		log.Fatalf("Error in ListenAndServe: %s", err)
	}
}

from atreugo.

savsgio avatar savsgio commented on July 19, 2024

I found the error in router. I will fix it.
It's due to the OPTIONS don't get to atreugo's router and middlewares are not executed.

from atreugo.

savsgio avatar savsgio commented on July 19, 2024

Hi @Chris533,

The bug is fixed, you could check it meanwhile in version:

go get github.com/savsgio/atreugo/v10@master

I will release a new version when CORS middleware will be added.

Thanks for your issue and for use Atreugo 😃

from atreugo.

Chris533 avatar Chris533 commented on July 19, 2024

Thansk! It's working well.

PR: #71

Check PR before reviewing the following, please.


I have tried to get the domain name of the browser request but failed (to define multiple origin domain names)

available

corsAllowOrigin = "*"
//or
corsAllowOrigin = "http://localhost:3000"

unavailable

corsAllowOrigin = "http://localhost:3000, http://localhost:8080"
//or
corsAllowOrigin = "http://localhost:3000 http://localhost:8080"
//or $2
corsAllowOrigin = string(ctx.URI().Scheme()) + "://" + string(ctx.Host())
//or $3
corsAllowOrigin = string(ctx.Request.Host())

So current CORS setting only supports all domains(*) or one domain

$2 $3 retrun Atreugo server host and port, e.g. localhost:8000, but web brower URI is http://localhost:3000/

The configuration of multiple domain names should list an array, and then compare the real requested domain name(web domian). If it matches, set the origin separately.

from atreugo.

savsgio avatar savsgio commented on July 19, 2024

Please read to gets more information about CORS: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

The Access-Control-Allow-Origin must be a one domain or *, not a list with domains.

I close this issue to continue in the PR

from atreugo.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.