簡體   English   中英

如何在 Grails 3.0.1 中啟用 CORS

[英]How to enable CORS in Grails 3.0.1

我想在服務器端使用 Grails 進行跨源通信。 我找到的唯一文檔就是這個

https://grails.org/plugin/cors

但這是針對舊版本的 Grails。 我發現的其他文檔是針對春季的:

https://spring.io/guides/gs/rest-service-cors/

所以我將文件SimpleCorsFilter.groovy添加到init/myproject/文件夾,但我不知道如何將此組件連接到resources.groovy

所以,如果你使用grails 3.2。+來到這里,你可以使用默認方式。

轉到您的application.yml並添加:

grails:
    cors:
        enabled: true

它將添加Access-Control-Allow-Origin '*' 如果您想要不同的東西,請查看此頁面

我們使用了一個普通的servlet過濾器和resources.groovy中的條目來解決這個問題:

public class CorsFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse resp, FilterChain chain)
            throws ServletException, IOException {

        String origin = req.getHeader("Origin");

        boolean options = "OPTIONS".equals(req.getMethod());
        if (options) {
            if (origin == null) return;
            resp.addHeader("Access-Control-Allow-Headers", "origin, authorization, accept, content-type, x-requested-with");
            resp.addHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS");
            resp.addHeader("Access-Control-Max-Age", "3600");
        }

        resp.addHeader("Access-Control-Allow-Origin", origin == null ? "*" : origin);
        resp.addHeader("Access-Control-Allow-Credentials", "true");

        if (!options) chain.doFilter(req, resp);
    }
}

resources.groovy:

beans = {
    corsFilter(CorsFilter)
}

這適用於使用基本身份驗證的CORS請求。 我編寫了Grails 2.x插件,這似乎比使用Grails 3更容易。

具體來說,這里有一些有用的代碼。 請注意,攔截器名稱必須與您的控制器名稱(此處為workRequest)匹配,域名需要是您要調用的任何內容(此處為localhost:8081),並且它是您想要的before()方法:

package rest
class WorkRequestInterceptor {
boolean before() { 
    header( "Access-Control-Allow-Origin", "http://localhost:8081" )
    header( "Access-Control-Allow-Credentials", "true" )
    header( "Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE" )
    header( "Access-Control-Max-Age", "3600" )  
    true 
}

boolean after() { true }
}

當我遇到CORS問題時,我正在使用emberjs框架和Grails 3.0休息應用程序。 按照本文中的步驟http://www.greggbolinger.com/rendering-json-in-grails-for-ember-js/幫助我進一步發展。

本文展示了如何使用新的Interceptor創建一個CorsInterceptor類來設置正確的標頭。

class CorsInterceptor {

  CorsInterceptor() {
    matchAll()
  }

  boolean before() {
    header( "Access-Control-Allow-Origin", "http://localhost:4200" )
    header( "Access-Control-Allow-Credentials", "true" )
    header( "Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE")
    header( "Access-Control-Max-Age", "3600" )
    true
  }

  boolean after() { true }
}

這對於GET請求按預期工作,但對POST和PUT請求失敗。 原因是OPTIONS預檢請求首先發送到http:// localhost:8080 / mycontroller / 1234 ,在我的情況下導致找不到404被返回。

在這個答案的幫助下https://stackoverflow.com/a/31834551我將CorsInterceptor類修改為:

class CorsInterceptor {

   CorsInterceptor() {
    matchAll()
  }

  boolean before() {
    header( "Access-Control-Allow-Origin", "http://localhost:4200" )
    boolean options = ("OPTIONS" == request.method)
    if (options) {

        header( "Access-Control-Allow-Origin", "http://localhost:4200" )
        header( "Access-Control-Allow-Credentials", "true" )
        header( "Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE")
        header( "Access-Control-Max-Age", "3600" )

        response.status = 200
    }

    true 
  }

  boolean after() { true }

}

現在POST和PUT請求正在運行。

你應該使用grails 3的新Interceptor API。 https://grails.github.io/grails-doc/3.0.x/guide/single.html#interceptors

您可以使用grails create-interceptor命令grails create-interceptor 對於CORS攔截器,我將使用此Interceptor的after()方法,並將其設置為匹配所有請求(或僅僅是您需要的請求)。 您可以在此方法中使用response對象,因此設置標題應類似於Spring文檔中描述的情況。

我發現的最干凈,最簡單的grails 3.1.x解決方案是添加Apache默認的CorsFilter:

import org.apache.catalina.filters.CorsFilter

// Place your Spring DSL code here
beans = {
    corsFilter(CorsFilter) //Custom CorsFilter under src/main/java/ works as well. I prefer Apache though...
}

來自#user215556的答案也可以,但Apache Cors過濾器的默認設置也可以

如果您需要為 Spring Security 核心/休息插件提供的端點啟用 CORS,您必須添加以下內容:

引導程序.groovy:

SpringSecurityUtils.clientRegisterFilter("corsFilter",
    SecurityFilterPosition.SECURITY_CONTEXT_FILTER.order - 1)

資源.groovy:

beans = {
    corsFilter(CorsFilter)
}

Grails 2.4.5 CORS 由於 HTTP/1.1 200 OK 在帶有“OPTIONS”標頭的瀏覽器預檢請求期間標頭中不存在@JeffScottBrown

@大衛廷克( https://github.com/davidtinker/grails-cors/issues/43

我剛剛安裝了 Cors 1.1.0 插件來處理 CORS 問題,但是由於瀏覽器沒有收到“http 狀態代碼 200 Ok”,我遇到了 CORS 問題。 我在 spring-security-core 插件版本方面受到限制,因為我正在開發一個舊版 Grails 2.4.5 應用程序,該應用程序需要一個 spring-security-core 版本,該版本僅適用於 nexus 中可用的 CORS 1.0.1 版本存儲庫。

我在我的 Grails 2.4.5 控制器中編寫了一些代碼來返回 200 狀態代碼,但是我不明白為什么 ReactJS 前端的瀏覽器沒有得到它。

我可以從帶有“curl”的命令行以及在瀏覽器中啟動后端時看到 200 個狀態代碼。

$ curl -i -v -H "Authorization: Bearer token" http://localhost:5000/server-app/api/v1/user/xxx
*   Trying 127.0.0.1:5000...
* Connected to localhost (127.0.0.1) port 5000 (#0)
> GET /server-app/api/v1/user/qatest1 HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/7.79.1
> Accept: */*
> Authorization: Bearer token
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
Server: Apache-Coyote/1.1
< Set-Cookie: JSESSIONID=xxx; Path=/server-web; HttpOnly
Set-Cookie: JSESSIONID=xxx; Path=/server-app; HttpOnly
< Content-Type: application/json;charset=UTF-8
Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
Transfer-Encoding: chunked
< Date: Wed, 12 Jan 2022 22:17:47 GMT
Date: Wed, 12 Jan 2022 22:17:47 GMT
<
{
  "id": xxx,
  "username": "xxx",
  "firstName": "xxx",
  "lastName": null,
  "department":
  [
    "{id:xx name:xxx, description:xxx}"
  ]
}* Connection #0 to host localhost left intact
cors.enable.logging = true // enable logging of failed requests
cors.url.pattern = '/api/v1/*'
cors.headers = ['Access-Control-Allow-Origin': 'http://localhost:3000', // Only allow access to that origin
                'Access-Control-Allow-Headers': '*',
                'Access-Control-Allow-Methods': 'GET, HEAD, TRACE, OPTIONS',
               ]
def index(){
        def users = User?.list(max:5, sort: "username", order:"asc")
        response.status = 200
        render(users as JSON)
    }
static mappings = {
        '/api/v1/users'(resources:'user')
        "/api/v1/user/$username"(controller:'user', action:"findByUsername", method: 'GET')
        ...
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM