Issues with post request in Flutter/Dart frontend with Go backend
In your code
http.post(url,body:json.encode(body)).then((http.Response response){
cookie = response.headers['session'];
});
debugPrint(cookie);
the line
debugPrint(cookie);
is executed before
cookie = response.headers['session'];
so it is expected that cookie
is null
when you print it. For some weird reason debugPrint(null)
throws an exception about "slit on null"
Try instead
http.post(url,body:json.encode(body)).then((http.Response response){
cookie = response.headers['session'];
debugPrint(cookie);
});

DanT29
Updated on December 05, 2022Comments
-
DanT29 6 months
I am new to Flutter/Dart, Go and mobile development in general. I am currently coding a login authentication page in flutter that connects to a backend written in go. To check if everything worked I wanted to print out the cookie that my backend sends back in the console. Unfortunately I am getting errors not sure what to do.
EDIT: I have been able to read the cookie, should I save the cookie in this format "session=UUID" or just the "UUID"? I want to send this cookie back in the header for future get requests. My Go code will check for the cookie name "session",but I'm not sure if sending it back in that format is correct.
Flutter code (I read on another stackoverflow post to use 10.0.2.2 as localhost when using an android emulator):
EDIT: After playing around with the code I was able to read the cookie in the header but it has the name as well not just the UUID.
import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; class Login extends StatefulWidget { @override State<StatefulWidget> createState(){ return new LoginState(); } } class LoginState extends State <Login> { final formKey = GlobalKey<FormState>(); String _email, _password; String cookie; void loginApi(){ var form = formKey.currentState; var url = "http://10.0.2.2:8080"; if (form.validate()) { form.save(); var body = { "Email":_email, "Pass":_password}; http.post(url,body:json.encode(body)).then((response){ print(response.headers['set-cookie']); }); } } @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text("Login"), backgroundColor: Colors.white, ), body: new Container( alignment: Alignment.center, child: Form( key: formKey, child: Column( children: <Widget>[ TextFormField( autocorrect: false, decoration: InputDecoration( labelText: "Email:", ), validator: (str) => !str.contains('@') ? "Not a Valid Email!" : null, onSaved: (str) => _email = str, ), TextFormField( autocorrect: false, decoration: InputDecoration( labelText: "Password:", ), validator: (str) => str.length <= 7 ? "Not a Valid Password!" : null, onSaved: (str) => _password = str, obscureText: false, ), RaisedButton( child: Text("Submit"), onPressed:loginApi, ), ], ) ), ), ); } }
Golang code (EDIT: Inserted a missing curly bracket after the panic error and deleted the curly bracket at the end of the code):
package main import ( "encoding/json" "html/template" "net/http" uuid "github.com/satori/go.uuid" "golang.org/x/crypto/bcrypt" ) type user struct { UserName string //Same as email Password []byte } type logindata struct { Email string Pass string } var tpl *template.Template var dbUsers = map[string]user{} var dbSess = map[string]string{} func init() { bs, _ := bcrypt.GenerateFromPassword([]byte("password"), bcrypt.MinCost) dbUsers["[email protected]"] = user{"[email protected]", bs} } func main() { http.HandleFunc("/", login) http.Handle("/favicon.ico", http.NotFoundHandler()) //Don't have favicon http.ListenAndServe(":8080", nil) } func login(w http.ResponseWriter, req *http.Request) { var data logindata decoder := json.NewDecoder(req.Body) err_decode := decoder.Decode(&data) if err_decode != nil { panic(err_decode) } u, ok := dbUsers[data.Email] if !ok { http.Error(w, "Username and/or password do not match", http.StatusForbidden) return } err_compare := bcrypt.CompareHashAndPassword(u.Password, []byte(data.Pass)) if err_compare != nil { http.Error(w, "Username and/or password do not match", http.StatusForbidden) return } // create session sID, _ := uuid.NewV4() c := &http.Cookie{ Name: "session", Value: sID.String(), } http.SetCookie(w, c) dbSess[c.Value] = data.Email return }
Output from console for flutter code (after I put in username and password and click submit, username is "[email protected]" password is "password"):
Performing hot reload... Reloaded 0 of 489 libraries in 544ms. I/flutter ( 3778): session=db3690d6-db6e-4658-8b5b-5f2d3f908a65
I also went to localhost:8080 on my browser expecting to show a blank page but it displayed "page not working" and my terminal outputted the following error I guess because I was accessing it with a browser and I wasn't sending in JSON data, not sure:
2018/05/24 23:29:38 http: panic serving [::1]:40010: EOF goroutine 6 [running]: net/http.(*conn).serve.func1(0xc82001a280) /usr/lib/go-1.6/src/net/http/server.go:1389 +0xc1 panic(0x76c6c0, 0xc82000a160) /usr/lib/go-1.6/src/runtime/panic.go:443 +0x4e9 main.login(0x7f96c9a848b8, 0xc82012c000, 0xc8201121c0) /home/daniel/Desktop/Workspace/Genesis/main.go:43 +0x176 net/http.HandlerFunc.ServeHTTP(0x8a8688, 0x7f96c9a848b8, 0xc82012c000, 0xc8201121c0) /usr/lib/go-1.6/src/net/http/server.go:1618 +0x3a net/http.(*ServeMux).ServeHTTP(0xc820013020, 0x7f96c9a848b8, 0xc82012c000, 0xc8201121c0) /usr/lib/go-1.6/src/net/http/server.go:1910 +0x17d net/http.serverHandler.ServeHTTP(0xc82001a100, 0x7f96c9a848b8, 0xc82012c000, 0xc8201121c0) /usr/lib/go-1.6/src/net/http/server.go:2081 +0x19e net/http.(*conn).serve(0xc82001a280) /usr/lib/go-1.6/src/net/http/server.go:1472 +0xf2e created by net/http.(*Server).Serve /usr/lib/go-1.6/src/net/http/server.go:2137 +0x44e 2018/05/24 23:29:38 http: panic serving [::1]:40012: EOF goroutine 18 [running]: net/http.(*conn).serve.func1(0xc82011c080) /usr/lib/go-1.6/src/net/http/server.go:1389 +0xc1 panic(0x76c6c0, 0xc82000a160) /usr/lib/go-1.6/src/runtime/panic.go:443 +0x4e9 main.login(0x7f96c9a848b8, 0xc8201161a0, 0xc820154000) /home/daniel/Desktop/Workspace/Genesis/main.go:43 +0x176 net/http.HandlerFunc.ServeHTTP(0x8a8688, 0x7f96c9a848b8, 0xc8201161a0, 0xc820154000) /usr/lib/go-1.6/src/net/http/server.go:1618 +0x3a net/http.(*ServeMux).ServeHTTP(0xc820013020, 0x7f96c9a848b8, 0xc8201161a0, 0xc820154000) /usr/lib/go-1.6/src/net/http/server.go:1910 +0x17d net/http.serverHandler.ServeHTTP(0xc82001a100, 0x7f96c9a848b8, 0xc8201161a0, 0xc820154000) /usr/lib/go-1.6/src/net/http/server.go:2081 +0x19e net/http.(*conn).serve(0xc82011c080) /usr/lib/go-1.6/src/net/http/server.go:1472 +0xf2e created by net/http.(*Server).Serve /usr/lib/go-1.6/src/net/http/server.go:2137 +0x44e 2018/05/24 23:29:43 http: panic serving [::1]:40016: EOF goroutine 7 [running]: net/http.(*conn).serve.func1(0xc82001a380) /usr/lib/go-1.6/src/net/http/server.go:1389 +0xc1 panic(0x76c6c0, 0xc82000a160) /usr/lib/go-1.6/src/runtime/panic.go:443 +0x4e9 main.login(0x7f96c9a848b8, 0xc82012c1a0, 0xc8201122a0) /home/daniel/Desktop/Workspace/Genesis/main.go:43 +0x176 net/http.HandlerFunc.ServeHTTP(0x8a8688, 0x7f96c9a848b8, 0xc82012c1a0, 0xc8201122a0) /usr/lib/go-1.6/src/net/http/server.go:1618 +0x3a net/http.(*ServeMux).ServeHTTP(0xc820013020, 0x7f96c9a848b8, 0xc82012c1a0, 0xc8201122a0) /usr/lib/go-1.6/src/net/http/server.go:1910 +0x17d net/http.serverHandler.ServeHTTP(0xc82001a100, 0x7f96c9a848b8, 0xc82012c1a0, 0xc8201122a0) /usr/lib/go-1.6/src/net/http/server.go:2081 +0x19e net/http.(*conn).serve(0xc82001a380) /usr/lib/go-1.6/src/net/http/server.go:1472 +0xf2e created by net/http.(*Server).Serve /usr/lib/go-1.6/src/net/http/server.go:2137 +0x44e
-
Günter Zöchbauer almost 5 yearsWhat were you tapping on to get this error?
-
DanT29 almost 5 yearsYes I tapped on the submit button
-
Günter Zöchbauer almost 5 yearsWhat line is
Login.dart:32:19
? -
DanT29 almost 5 yearsdebugPrint(cookie); part of the loginApi function I made for the onPressed field for the raised button
-
Günter Zöchbauer almost 5 yearsCan you try
print(cookie)
instead ofdebugPrint(cookie)
or perhapsprint(response.headers);
? I get the impression there is something fishy going on with the headers. -
DanT29 almost 5 yearsit is showing this as the error: I/flutter ( 5490): null for print(cookie), I will try the other one now
-
Günter Zöchbauer almost 5 yearsThat doesn't look like an error.
-
DanT29 almost 5 yearsIn my loginApi function I changed my debugPrint(cookie) to print(cookie), the output of the console just showed me this after putting in the username and password: Performing full restart... Restarted app in 2,049ms. W/IInputConnectionWrapper( 5490): getCursorCapsMode on inactive InputConnection I/flutter ( 5490): null
-
Günter Zöchbauer almost 5 yearsThat doesn't look like an error, just that
response.headers['session']
returnsnull
. -
DanT29 almost 5 yearsI can't seem to code print(response.headers) it is underlining response saying "undefined name response"
-
Anzel almost 5 years@DanT29, under your go code, are you sure you have put the closing
}
parentheses at the right place? You didn't close it after thepanic(error)
line seems very odd to me. The remaining code is unreachable -
DanT29 almost 5 years@Anzel good call! my post requests are working on postman when i use raw JSON now. I'm still getting errors but will update my question details.
-
-
DanT29 almost 5 yearsI still seem to be getting the same error, could this be an issue on my back-end? I think I'm retrieving the headers correctly.
-
Günter Zöchbauer almost 5 yearsSame error as which one? "The method 'split' was called on null."? Then you don't get headers back. Perhaps you should check the
responseCode
-
DanT29 almost 5 yearsYes it showed me this : E/flutter ( 5490): [ERROR:topaz/lib/tonic/logging/dart_error.cc(16)] Unhandled exception: E/flutter ( 5490): NoSuchMethodError: The method 'split' was called on null. E/flutter ( 5490): Receiver: null E/flutter ( 5490): Tried calling: split("\n") ...followed by a bunch of other errors. I will try to look over my backend code...I'm guessing from what you see my post request is correct?