I did authorization via http. post, send a JSON Body with username and password, in the response I get a Header, the Header has a token, it is stored in 'set_cookie: Authorization=token', how do I get it and write it to the storage?
You can get the cookie from the response of login request using the following code
HttpClient _httpClient = new HttpClient();
HttpClientRequest request = await _httpClient.postUrl(Uri.parse(url));
request.headers.set('content-type', 'application/json');
request.add(utf8.encode(json.encode(jsonMap)));
HttpClientResponse response = await request.close();
print(response.cookies); // this is a List<Cookie>, you can iterate and find the required cookie
Now you can store the cookie using shared_preference plugin, and use it in your all the future requests.
HttpClient client = new HttpClient();
HttpClientRequest clientRequest =
await client.getUrl(Uri.parse("http: //www.example.com/"));
clientRequest.cookies.add(Cookie("sessionid", "asdasdasqqwd"));
You can also explore dio library and use AuthInterceptor to add the token for all the requests for you.
Related
I am doing a post request in flutter to a google cloud function:
final uri = Uri.parse(
'https://example.cloudfunctions.net/send_to_queue');
final bearer = 'Bearer ${await user.getIdToken()}';
final response = await http.post(uri, body: json.encode(data),
headers: {HttpHeaders.authorizationHeader: bearer, 'Content-Type': 'application/json'});
In the Google Cloud I print(request.headers) I see a bunch of headers but no Authorization or Content-Type headers.
What should I do?
P.S. Same issue in here Flutter calling firebase cloud function admin.auth.updateUser but I don't want to use a callable function
The browser was sending an OPTIONS request (preflight) before the POST.
I needed to change the Google Cloud Function to handle this:
def main(request):
# Set CORS headers for the preflight request
if request.method == 'OPTIONS':
# Allows GET requests from any origin with the Content-Type
# header and caches preflight response for an 3600s
headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
'Access-Control-Max-Age': '3600'
}
return ('', 204, headers)
# Get token from request
token = request.headers.get('Authorization').split('Bearer ')[1]
etc..
I would like to do a set cookies, do a get request and after get the cookies.
In python it will be this:
> import requests cookies = {'status': 'working','color':'blue'}
> response = session.get('https://google.com/', cookies=cookies)
> print(session.cookies.get_dict())
Do you know how to flutter it? I tried something like this but it doesn't seem to have a cookie in the response and the cookie doesn't seem to be sent
Map<String, String> headers = {
"status":"working",
"color":"blue"
};
final BaseOptions dioBaseOptions = BaseOptions(
baseUrl: 'https://google.com',
headers: {
'Cookie': headers,
},
);
dio = Dio(dioBaseOptions);
var cookieJar=CookieJar();
dio.interceptors.add(CookieManager(cookieJar));
var response = await dio.get('https://google.com/');
Cookie is set by a server in a response header and a browser sends it back in a request header.
After receiving an HTTP request, a server can send one or more Set-Cookie headers with the response. The browser usually stores the cookie and sends it with requests made to the same server inside a Cookie HTTP header.
See Using HTTP cookies for details.
CookieManager does this for dio and Flutter.
To access Cookies in a dio response
final cookies = response.headers['set-cookie']
Friends
I am accessing an API using bearer token authorization and getting HTTP status 401.
The problematic code is Dart code (in a Flutter app). I have Swift code that accesses the same API so I can check the headers I am passing.
The Dart code:
var client = http.Client();
var url = Uri.https(<site>, <path>);
Map<String, String> body = {
<Hash entries to define request>
};
var headers = <String, String>{
"Content-Type" : "application/x-www-form-urlencoded; charset=UTF-8",
"Accept" : "application/json, text/javascript, */*; q=0.01",
"Authorization" : "Bearer <Hex token>",
};
var response = await client.post(url, headers: headers, body: body);
http is from: import 'package:http/http.dart' as http;
The hex token is taken from a successful login. It is the same as I see after a successful login with the Swift app.
The "Accept" and "Content-Type" are also the same as the Swift app.
In result the statusCode is 401 and reasonPhrase is "Unauthorized"
The Swift app is working perfectly
This was not the problem I thought.
The Authorization header is ignored by the server and it does some cookie magic to authorise.
In Swift the cookies were set without my intervention. So I never understood that the Bearer.... authorization was ignored.
I'm trying to upload a video file to GCS using a pre-signed url. I've managed to create the url via Google but now I am facing a problem using it.
Upload works in Postman, got response 200.
postman body, postman params
Code copied from Postman results in 403 Forbidden (SignatureDoesNotMatch):
Future<http.StreamedResponse> uploadVideo(
{required String uploadURL, required String filePath}) async {
var headers = {'Content-Type': 'application/octet-stream'};
var request = http.MultipartRequest('PUT', Uri.parse(uploadURL));
request.files.add(await http.MultipartFile.fromPath('file', filePath));
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
print(await response.stream.bytesToString());
} else {
print(response.reasonPhrase);
}
return response;
}
This is the error I am getting from Google:
<?xml version='1.0' encoding='UTF-8'?><Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.</Message><StringToSign>GOOG4-RSA-SHA256
20210803T082850Z
20210803/auto/storage/goog4_request
6d513846a3db49f949b0d2eea8f04b90f918b3b94588c3ed55ed3620b7d7e1f6</StringToSign><CanonicalRequest>PUT
/phonedo-interviews/app-test/007/2.mp4
X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=interviews%40interviews-317011.iam.gserviceaccount.com%2F20210803%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20210803T082850Z&X-Goog-Expires=900&X-Goog-SignedHeaders=content-type%3Bhost
content-type:multipart/form-data; boundary=dart-http-boundary-6w1yq6BQN3EkGBrhHZnwidOXZsBecsgSwTT3nBjB9vQCToHt0cg
host:storage.googleapis.com
content-type;host
UNSIGNED-PAYLOAD</CanonicalRequest></Error>
Note: I needed Content-Type to be application/octet-stream so I disabled that header in Postman's automatic headers and added Content-Type manually. When I didn't do that I also got 403.
The solution was to send the file in binary.
Here is the working code:
Future<http.Response> uploadVideo(
{required String uploadURL, required String filePath}) async {
var response = await http.put(
Uri.parse(uploadURL),
headers: {'content-type': 'application/octet-stream'},
body: File(filePath).readAsBytesSync(),
);
In your Postman headers, a Token is given to GCS (first line). Given that you need authorization, Postman probably has this Token saved somewhere application-wise.
In this flutter code, the headers you're giving do not include an Auth token and therefore you're receiving a 403 error.
var client = new RestClient("https://app.vssps.visualstudio.com/_apis/profile/profiles/me?api-version=1.0");
var request = new RestRequest(Method.GET);
var authenHeader = new AuthenticationHeaderValue("Bearer",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", username, password))));
request.AddHeader("Authorization", authenHeader.ToString());
request.AddHeader("Accept", "application/json");
IRestResponse response = client.Execute(request);
Response :
StatusCode: NonAuthoritativeInformation,
Content-Type: text/html;
.
.
Or this request can use only personal access token to get it?
You must use OAuth with the profiles API, it doesn't support basic auth.