Vue + Golang : Access to XMLHttpRequest at [Apiurl] from origin has been blocked by CORS policy: Request header field authorization is not allowed

huangapple go评论89阅读模式
英文:

Vue + Golang : Access to XMLHttpRequest at [Apiurl] from origin has been blocked by CORS policy: Request header field authorization is not allowed

问题

我是Vuejs和golang的初学者。当我尝试通过Vue axios调用API时,在请求头中发送授权令牌时,我遇到了以下错误。

访问' http://localhost:5000/greet/hello '的XMLHttpRequest来自' http://localhost:5500 '的源被CORS策略阻止:预检响应中不允许请求头字段授权。

[实际上,我在另一个项目中遇到了错误。但为了理解解决方案,我在以下简单项目中实现了这个。所以任何人都可以在他们的端上测试代码并提供解决方案]

App.go

package main

import (
    "fmt"

    "github.com/gin-contrib/cors"
    "github.com/gin-gonic/gin"
)

func main() {
    router := gin.Default()
    router.Use(cors.Default())
    router.Use(Authenticate())

    v1 := router.Group("/greet")
    {
        v1.POST("/hello", handleFunc)
    }
    router.Run(":5000")
}

func handleFunc(c *gin.Context) {
    var student struct {
        Name string `json:"name"`
    }

    if c.BindJSON(&student) != nil {
        c.JSON(400, gin.H{"message": "Provide required details."})
        c.Abort()
        return
    }

    message := fmt.Sprintf("%s%s", "Good Morning ", student.Name)

    c.JSON(200, gin.H{"message": message})
}

func Authenticate() gin.HandlerFunc {

    return func(c *gin.Context) {

        requiredToken := c.Request.Header["Authorization"]

        if len(requiredToken) == 0 {
            c.JSON(400, gin.H{"message": "No token found"})
            c.Abort()
            return
        }

        fmt.Println(requiredToken)

        c.Next()
    }
}

index.html

<html>
    <head>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js"></script>
    </head>
    <body>
        <div id="app" class="container m-5">
            <p>{{name}}</p>
            <input type="text" class="form-control col-3" placeholder="Enter Name" v-model="name"/><br>
            <button @click="onButtonClick" class="btn btn-info">CALL API</button>
        </div>
        <script src="index.js"></script>
    </body>
</html>

index.js

var app = new Vue({
  el: '#app',
  data: {
    name: ""
  },
  methods: {
    onButtonClick() {
      axios
        .post("http://localhost:5000/greet/hello",
          {
            Name: this.name
          },
          {
            headers: {
              Authorization: "HEY"
            }
          })
        .then((response) => {
          if (response.status == 200) {
            alert(response.data.message);
          }
        })
        .catch((error) => {
          console.log(error);
          alert(error.response.data.message);
        });
    },
  }
})
英文:

I am beginner to Vuejs & golang.
I got following error when I try to send Authorization token thorugh header while calling api from vue axios.

Access to XMLHttpRequest at 'http://localhost:5000/greet/hello' from origin 'http://localhost:5500' has been blocked by CORS policy: Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response.

[Actually I got error in my another project. but to understand solution I implement this in simple following project. So anyone can test code at their end and provide solution]

App.go

package main

import (
	&quot;fmt&quot;

	&quot;github.com/gin-contrib/cors&quot;
	&quot;github.com/gin-gonic/gin&quot;
)

func main() {
	router := gin.Default()
	router.Use(cors.Default())
	router.Use(Authenticate())

	v1 := router.Group(&quot;/greet&quot;)
	{
		v1.POST(&quot;/hello&quot;, handleFunc)
	}
	router.Run(&quot;:5000&quot;)
}

func handleFunc(c *gin.Context) {
	var student struct {
		Name string `json:&quot;name&quot;`
	}

	if c.BindJSON(&amp;student) != nil {
		c.JSON(400, gin.H{&quot;message&quot;: &quot;Provide required details.&quot;})
		c.Abort()
		return
	}

	message := fmt.Sprintf(&quot;%s%s&quot;, &quot;Good Morning &quot;, student.Name)

	c.JSON(200, gin.H{&quot;message&quot;: message})
}

func Authenticate() gin.HandlerFunc {

	return func(c *gin.Context) {

		requiredToken := c.Request.Header[&quot;Authorization&quot;]

		if len(requiredToken) == 0 {
			c.JSON(400, gin.H{&quot;message&quot;: &quot;No token found&quot;})
			c.Abort()
			return
		}

		fmt.Println(requiredToken)

		c.Next()
	}
}

index.html

&lt;html&gt;
    &lt;head&gt;
        &lt;script src=&quot;https://cdn.jsdelivr.net/npm/vue/dist/vue.js&quot;&gt;&lt;/script&gt;
        &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js&quot;&gt;&lt;/script&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;div id=&quot;app&quot; class=&quot;container m-5&quot;&gt;
            &lt;p&gt;{{name}}&lt;/p&gt;
            &lt;input type=&quot;text&quot; class=&quot;form-control col-3&quot; placeholder=&quot;Enter Name&quot; v-model=&quot;name&quot;/&gt;&lt;br&gt;
            &lt;button @click=&quot;onButtonClick&quot; class=&quot;btn btn-info&quot;&gt;CALL API&lt;/button&gt;
        &lt;/div&gt;
        &lt;script src=&quot;index.js&quot;&gt;&lt;/script&gt;
    &lt;/body&gt;
&lt;/html&gt;

index.js

var app = new Vue({
  el: &#39;#app&#39;,
  data: {
    name: &quot;&quot;
  },
  methods: {
    onButtonClick() {
      axios
        .post(&quot;http://localhost:5000/greet/hello&quot;,
          {
            Name: this.name
          },
          {
            headers: {
              Authorization: &quot;HEY&quot;
            }
          })
        .then((response) =&gt; {
          if (response.status == 200) {
            alert(response.data.message);
          }
        })
        .catch((error) =&gt; {
          console.log(error);
          alert(error.response.data.message);
        });
    },
  }
})

答案1

得分: 2

基本上,当发送授权头时,不允许使用Allowed-Origin: *,所以你需要指定允许的域名。你可以通过更改CORS中间件来实现这一点,而不是使用默认的router.Use(cors.Default())

你可以像这样使用:

router.Use(cors.New(cors.Config{
	AllowOrigins:     []string{"http://localhost:5500"},
	AllowMethods:     []string{"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"},
	AllowHeaders:     []string{"Origin", "Content-Length", "Content-Type", "Authorization"},
	ExposeHeaders:    []string{"Content-Length"},
	AllowCredentials: true,
	MaxAge: 12 * time.Hour,
}))

你还可以使用AllowOriginFunc cors.Config 属性来实现动态逻辑(如果你想支持多个域名)。

注意,AllowOrigin 属性包含你的 Vue 项目的域名。显然,你可以允许更多的头部,但这里列出的是你之前使用默认配置允许的头部。

英文:

Basically you are not allowed to have Allowed-Origin: * when sending the Authorization header so you'll have to specify the domain that is allowed, you can achieve this by changing the CORS middleware instead of using the default router.Use(cors.Default())

you could use something like this

router.Use(cors.New(cors.Config{
	AllowOrigins:     []string{&quot;http://localhost:5500&quot;},
	AllowMethods:     []string{&quot;GET&quot;, &quot;POST&quot;, &quot;PUT&quot;, &quot;PATCH&quot;, &quot;DELETE&quot;, &quot;HEAD&quot;},
	AllowHeaders:     []string{&quot;Origin&quot;, &quot;Content-Length&quot;, &quot;Content-Type&quot;, &quot;Authorization&quot;},
	ExposeHeaders:    []string{&quot;Content-Length&quot;},
	AllowCredentials: true,
	MaxAge: 12 * time.Hour,
}))

you can also use the AllowOriginFunc cors.Config property for a dynamic logic (in case you want to support multiple domains).

Notice how the AllowOrigin property contains the domain of your vue project. Obviously you can allow more headers but the ones listed here are the ones you were allowing previously by using the Default config

huangapple
  • 本文由 发表于 2021年6月16日 23:51:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/68006117.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定