Go 后端和 flutter web 上的 CORS 问题

问题描述 投票:0回答:1

我创建了一个需要从 golang 后端加载的 flutter http 函数。我已经允许 go 后端中的所有来源,但 flutter web 仍然返回 cors 问题。我的 golang 版本可能有问题吗?或者也许是颤振网络? 以下是我的Go God:

    func main() {
db, err := NewDB()
if err != nil {
    panic("Failed to connect to database")
}
CreateTables(db)
// Seed currencies
if err := SeedCurrencies(db.DB); err != nil {
    panic("failed to seed currencies")
}

config := cors.Config{
    AllowOrigins: []string{"https://app.mam-laka.com", "*mam-laka.com", "*"}, // Allow all origins
    AllowMethods: []string{"GET", "POST", "PUT", "DELETE"},                   // Allowed HTTP methods (adjust as needed)
    AllowHeaders: []string{"Origin", "Content-Type", "Accept",
        "Authorization", "Access-Control-Allow-Origin"}, // Allowed request headers
    ExposeHeaders:    []string{"Content-Length"}, // Headers that can be exposed to the browser
    AllowCredentials: true,                       // Allows sending cookies and credentials like authorization tokens
    MaxAge:           12 * time.Hour,             // Cache preflight responses for 12 hours
}
r := SetupRouter(db)
r.Use(cors.New(config))
r.Run(":8091")

}

如上图,我已经处理了cors golang部分。在 flutter 代码中,该函数如下所示:

Future signIn() async {
Map<String, dynamic> body = {
  "email": email.text,
  "password": password.text,
};

try {
  setState(() {
    isLoading = true;
  });

  Map<String, String> headers = {
    "Content-Type": "application/json",
  };

  var url = Uri.parse('$baseurl/login');
  var response =
      await http.post(url, headers: headers, body: jsonEncode(body));
  Map data = jsonDecode(response.body);
  print(data);

  if (response.statusCode == 200 && data["message"] == "Login successful") {
    var box = await Hive.box('myBox');
    box.put('token', data['token']);

    box.put('names', '${data['user']['fname']} ${data['user']['lname']}');
    box.put('email', data['user']['email']);
    print(box.get("email"));

     print(box.get("names"));
    Navigator.push(
      context,
      PageTransition(
        type: PageTransitionType.rightToLeft,
        child: Bottomnav(),
      ),
    );

    showTopSnackBar(
      Overlay.of(context),
      CustomSnackBar.success(
        message: data["message"],
      ),
    );
  } else if (response.statusCode == 401) {
    showTopSnackBar(
      Overlay.of(context),
      CustomSnackBar.error(
        message: "Invalid credentials. Please try again.",
      ),
    );
  } else {
    showTopSnackBar(
      Overlay.of(context),
      CustomSnackBar.error(
        message: data["message"] ?? "An error occurred. Please try again.",
      ),
    );
  }
} catch (e) {
  print("This is e $e");

  showTopSnackBar(
    Overlay.of(context),
    const CustomSnackBar.error(
      message: "Check your internet connection",
    ),
  );
} finally {
  setState(() {
    isLoading = false;
  });
}

}

flutter dart go cors
1个回答
0
投票

CORS 每次只能接受一个值,因此您可以为所有值添加一个 FQDN 或 *。

我在下面留下了部分简单代码,例如如何在你的 api 代码中允许 CORS

// EXAMPLE TO USE CORS IN A GO API
package main

import (
    "log"
    "net/http"
    "os"
    "strings"
)

func apiHandler(w http.ResponseWriter, r *http.Request) {
    // Set Content-Type based in the router {response}
    contentType := r.Header.Get("Content-Type")
    
    // allows the counterparty to define the content-type
    switch contentType {
    case "application/json":
        w.Header().Set("Content-Type", "application/json")
    case "text/plain":
        w.Header().Set("Content-Type", "text/plain")
    case "text/html":
        w.Header().Set("Content-Type", "text/html")
    case "application/xml":
        w.Header().Set("Content-Type", "application/xml")
    default:
        w.Header().Set("Content-Type", "text/plain")
    }

    // CORS CONTROL
    w.Header().Set("Access-Control-Allow-Credentials", "true")
    w.Header().Set("Access-Control-Allow-Origin", "https://app.mam-laka.com")
    w.Header().Set("Access-Control-Allow-Headers", "Authorization, Content-Type")
    w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") // Other options: GET,PUT,POST,DELETE,PATCH,OPTIONS,HEAD
    w.Header().Set("Vary", "Origin")

    // CACHE AND CONTROL
    w.Header().Set("Cache-Control", "no-cache, private, max-age=0") // "max-age=3600"
    w.Header().Set("Pragma", "no-cache")
    w.Header().Set("X-Content-Type-Options", "nosniff")
    w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains")

    // Obfuscating server information
    serverHeader := "GO WebServer - I am a teapot"
    w.Header().Set("Server", serverHeader)

    // Get API name from Request
    apiName := r.PathValue("api")

    // Get API Authorization from Request (Bearer <token>)
    authToken := r.Header.Get("Authorization")

    // Split parameters and authorization from header
    authParts := strings.Split(authToken, "Bearer ")

    // Permit preflight CORS from Browsers and Deny Bearer Token missing
    if len(authParts) < 2 {
        http.Error(w, "%s", http.StatusOK) // Return status 200 to permit CORS check
        return                             // Stop access and Deny continue
    }

    // If everything it's ok with Bearer Token get token from Authorization: Bearer <token>
    apiKey := authParts[1]

    // Set Bearer <token> to header 
    r.Header.Set("Authorization", "Bearer "+apiKey)

    // Get URL
    urlPath := r.URL.Path

    // Check API to validate Key
    /* 
     *  Create your logic to control apiKey and who can access your system
     *
    */

    // Main API Proccess
    /* 
     *  Create your logic to permit access to your internal calls
     *  for example, you can create a internal function to pass apiName and other stuff's, something like:
     *  ok := api.GetLogin(&apiName, &urlPath, w)    
     *
    */  

    // If everything's OK return Status 200 or something like that
    if ok == nil {      
        w.WriteHeader(http.StatusOK)
    }
}

func main() {

    // Check database availability (create your database connection first)
    db, err := database.OpenConnection()
    if err != nil {
        log.Fatal("Error: Database connection failed")
    }
    db.Close()

    // Initiate Web Server with handle
    http.HandleFunc("/api/{api}/", apiHandler)
    err = http.ListenAndServeTLS(":8091", "ssl/cert.pem", "ssl/cert.key", nil)
    if err != nil {
        log.Fatal("Web Server Error [check tcpPort and SSL Certs] ", err)
    }
}

我知道这个例子不是你问题的正确答案,但我希望这个逻辑的一部分对你有帮助。

再见 亚历克斯·曼弗林 github.com/mitvix

© www.soinside.com 2019 - 2024. All rights reserved.