Can't Access Cookie in HTTP Response with Flutter - http

I'm working on Flutter an app which will use Express based REST api. While implementing Cookie based sessions, I wanted to retrieve cookies from app with basic auth request but somehow I can't retrieve cookies in response. When I make the same request from Postman, there is no problem, cookies are setted automatically.
I am using HTTP package to make request and code is quite straightforward as below.
void login(String username, String password) async {
var url = 'http://$username:$password#111.222.333.444:3333/auth';
var response = await http.get(url);
print('Response header: ${response.headers}');
print('Response status: ${response.statusCode}');
print('Response body: ${response.body}');
}
There is no cookie in header or body of response.

If you want to get cookie values from HTTP response in flutter
String rawCookie = response.headers['set-cookie']!;
int index = rawCookie.indexOf(';');
String refreshToken = (index == -1) ? rawCookie : rawCookie.substring(0, index);
int idx = refreshToken.indexOf("=");
print(refreshToken.substring(idx+1).trim());

You have to call 'set-cookie' in header:
var cookies = response.headers['set-cookie'];

http package
get and post actions are sending the request without cookies so you should put the cookies manually like this:
Response response = await get(url, headers: {'cookie': 'session_id=ufe1nfq69mdi67pnql6n1cs3cv; path=/; HttpOnly='});
But there is an easy way to do that without putting cookies manually by requests package
import 'package:requests/requests.dart';
// ...
// For example post some login request
var url = "http://yourApilink";
var body = Map<String, dynamic>();
body["username"] = username;
body["password"] = password;
var request = await Requests.post(url, body: body);
request.raiseForStatus();
if(request.statusCode==200) {
//Successful
var statusJson = json.decode(utf8.decode(request.bytes()));
//....
// Example for get some other actions
var url = "http://yourApilink";
var request = await Requests.get(url);
request.raiseForStatus();
print(request.json()['userid']);
if(request.statusCode==200) {
//Successful
var statusJson = json.decode(utf8.decode(request.bytes()));
//....

Related

How to make a HTTP get call with request header in ASP.NET MVC to an API with Oauth2 authorization?

I'm having a hard time executing a http get call with headers to an api with oauth2 authorization.
I already tried the code below but then I'm receiving an Unauthorized response from the api. I think the problem is that because I've executed the GETASYNC() without the adding some headers. Can you help me to find a way on how to add headers before I execute the GETASYNC().
public HttpClient webApiClient = new HttpClient();
public async System.Threading.Tasks.Task<ActionResult> Index()
{
var uri = new Uri("https://myURL.com/"+ transno);
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var response = await webApiClient.GetAsync(uri);
response.Headers.Add("Accept", "application/json");
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
response.Headers.Add("client-id", "clientid");
response.Headers.Add("client-secret", "clientsecret");
response.Headers.Add("partner-id", "partnerid");
var result = JObject.Parse(await response.Content.ReadAsStringAsync());
}

POSTing data while redirecting to a third-party URL using Response.Redirect()

In ASP.Net Core 2.0, how can I POST data while redirecting to a third-party URL using Response.Redirect()?
Note: I have to POST this data without using the query-string.
Response.Redirect triggers a GET request which means that the only option is using a query string.
Can you trigger the redirection from the client (if any) in order to make a POST request?
You must use object if you want post data without using query string.
[HttpPost]
public IActionResult Search([FromBody] CustomerSearchRequestApiModel request)
{
if (request == null)
{
return BadRequest();
}
return Ok(request);
}
It is impossible to use Response.Redirect() to send Post request.
For a workaround, you could try HttpClient to send Post request and then return the reponse to the web browser with ContentResult as text/html.
Here is a demo code:
public async Task<ContentResult> HtmlView()
{
using (var formDataContent = new MultipartFormDataContent())
{
HttpClient client = new HttpClient();
Article article = new Article { ArticleName = "AN" };
formDataContent.Add(new StringContent("AN", Encoding.UTF8, "application/json"), "ArticleName");
using (HttpClient httpClient = new HttpClient())
{
HttpResponseMessage response = await httpClient.PostAsync(#"https://localhost:44393/Articles/Create", formDataContent);
return new ContentResult
{
ContentType = "text/html",
StatusCode = (int)response.StatusCode,
Content = await response.Content.ReadAsStringAsync()
};
}
}
}
Note
Change the HttpClient part to send the right request to your own third party url with validate parameters.

twitter search Api RestSharp not working and giving error unauthorize

I am trying to develop twitter client. i am using RestSharp for api. its work fine with authentication and gettimeline but its give error when i try to search twitter with # hashtag . its gives error like bad request and unauthorized.
Working code
public string GetTimeLine(string key,string secret,string userToken,string userSecret)
{
var request = new RestRequest("/1.1/statuses/user_timeline.json", Method.GET);
Client.Authenticator = OAuth1Authenticator.ForProtectedResource(key, secret, userToken, userSecret);
var response = Client.Execute(request);
return response.Content;
}
Respond with unauthorized error:
public string GetHashtag(string key, string secret, string userToken, string userSecret)
{
var request = new RestRequest("/1.1/search/tweets.json?q=%23freebandnames", Method.GET);
Client.Authenticator = OAuth1Authenticator.ForProtectedResource(key, secret, userToken, userSecret);
var response = Client.Execute(request);
return response.Content;
}
Try this:
var request = new RestRequest("/1.1/search/tweets.json?q={query}", Method.GET);
request.AddUrlSegment("query", "#freebandnames");

OneDrive for Business :"invalid_request","error_description":"AADSTS90014: The request body must contain the following parameter: 'grant_type

I'm trying to integrate the OneDrive for Busines to a Web Form App.
For this I use the documentation given at this url
In web Form App I have two Pages:
First one is Login page which have a button for login
On login button click I create a GET Request to OneDrive for Business API using the following code:
HttpClient client = new HttpClient();
Redirecturi = Uri.EscapeDataString(Redirecturi);
string url = string.Format("https://login.windows.net/common/oauth2/authorize?response_type=code&client_id={0}&redirect_uri={1}", ClienId, Redirecturi);
var response = client.GetAsync(url);
var json = response.Result.Content.ReadAsStringAsync();
Label2.Text = json.Result;
When I click the login button it takes me to micorosoft login service and sends me back to callback.aspx page with access code (Redirect URI configured on azure)
I got the access code.
On the second page I redeem the access code and make a POST request to get the Authentication token.
Here is the code for the second page:
private string BaseUri="https://login.windows.net/common/oauth2/token";
public string Redirecturi = "http://localhost:51642/CallBack.aspx";
public string ResourcesId = "https://api.office.com/discovery/";
private string ClienId = "180c6ac4-5829-468e-.....-822405804862"; ///truncated//azure
private string ClientSecert = "G4TAQzD8d7C4...OE6m366afv8XKbTCcyXr4=";//truncated
protected void Page_Load(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(Request.QueryString[OAuthConstants.AccessToken]))
{
// There is a token available already. It should be the token flow. Ignore it.
return;
}
if (!string.IsNullOrEmpty(Request.QueryString[OAuthConstants.Code]))
{
string _accessCode = Request.QueryString[OAuthConstants.Code];
HttpClient client = new HttpClient();
// BaseUri = Uri.EscapeDataString(BaseUri);
Redirecturi = Uri.EscapeDataString(Redirecturi);
ResourcesId = Uri.EscapeDataString(ResourcesId);
string url = string.Format("{0}?client_id={1}&redirect_uri={2}&grant_type=authorization_code&client_secret={3}&code={4}&grant_type=authorization_code&resource={5}", BaseUri, ClienId, Redirecturi, ClientSecert, _accessCode, ResourcesId);
var response = client.PostAsync(url, null);
var json = response.Result.Content.ReadAsStringAsync();
Response.Write(json);
}
}
But instead of Response I am get the following error. Which say include the grant_type in url. I have already added (you can check in code).
I get same error the same error without including it.
Here is the error
{"error":"invalid_request","error_description":"AADSTS90014: The request body must contain the following parameter: 'grant_type'.\r\nTrace ID: 2adb3a7f-ceb1-4978-97c4-3dc2d3cc3ad4\r\nCorrelation ID: 29fb11a0-c602-4891-9299-b0b538d75b5f\r\nTimestamp: 2015-07-15 09:58:42Z","error_codes":[90014],"timestamp":"2015-07-15 09:58:42Z","trace_id":"2adb3a7f-ceb1-4978-97c4-3dc2d3cc3ad4","correlation_id":"29fb11a0-c602-4891-9299-b0b538d75b5f","submit_url":null,"context":null}
Please help to know where or what is getting wrong.
Any kind of help will be appreciable
You're adding the parameters to the request querystring. You have to post the data in the request body.
var content = new StringContent(
"grant_type=authorization_code" +
"&client_id=" + ClienId +
"&redirect_uri=" + Redirecturi +
"&client_secret=" + ClientSecert +
"&code=" + _accessCode +
"&resource=" + ResourcesId,
Encoding.UTF8,
"application/x-www-form-urlencoded");
var response = httpClient.PostAsync(BaseUri, content);
var result = response.Result.Content.ReadAsStringAsync();
use FormUrlEncodedContent instead of StringContent (form data post)
var formContent = new FormUrlEncodedContent(new Dictionary<string, string>
{
{ "client_id", clientId },
{ "client_secret", clientSecret },
{ "code", authCode },
{ "redirect_uri", redirectUri },
{ "grant_type", "authorization_code" }
});
var response = await httpClient.PostAsync("https://login.microsoftonline.com/common/oauth2/token", formContent);
Sharing for future readers because this error is not specific to OneDrive only but can arise in other Microsoft tools
I was getting this error when working with Microsoft Bot Framework's Skype bot. In my case the bot file the appId and appSecret was wrongly set to clientId and clientSecret
Changing the same to appId and appSecret fixed the issue.

How do I get the current cookie / session ID from a HttpResponseMessage?

I try to use the new .net 4.5 HttpClient from System.net.http.
I set-up my client like this
CookieContainer cookieJar = new CookieContainer();
HttpClientHandler handler = new HttpClientHandler
{
CookieContainer = cookieJar,
AllowAutoRedirect = true
};
handler.UseCookies = true;
handler.UseDefaultCredentials = false;
HttpClient client = new HttpClient(handler as HttpMessageHandler);
then I do a client.GetAsync(url)
now I am inspecting the response and try to get the cookie / session values for a following post.
I try to test a login scenario of an existing page via code...
How do I get the cookie information in a response? Or do I walk on a wrong path here?
Any explanation would be fantastic...
The cookie exists in the form of a header that is the instruction to create the cookie on the client. Those headers have the form of "Set-Cookie" as the actual header, with the value of "CookieTitle={form encoded value}". Getting that cookie looks like this:
var cookieTitle = "MyCookieTitle";
var response = ... // get response object
var cookie = response.Headers.GetValues("Set-Cookie").First(x => x.StartsWith(cookieTitle));
That gets you the raw string of the header, which will look like this:
CookieTitle=this+is+the+value+of+the+cookie
You can check the 'Set-Cookie' header of the HTTP response.
You don't need to get the cookies and re-specify them for your next POST. The HttpClient will take care of doing that for you.
As long as the URL that you are POSTing to is within the path that was defined by the cookie then the cookie will automatically be resent with the request.
For example, if you create your cookie like this,
public class CookieController : ApiController
{
public HttpResponseMessage Get() {
var httpResponseMessage = new HttpResponseMessage();
var cookieHeaderValues = new List<CookieHeaderValue>();
cookieHeaderValues.Add(new CookieHeaderValue("foo","bar")
{Domain = "myhost",Path = "/"});
httpResponseMessage.Headers.AddCookies(cookieHeaderValues);
return httpResponseMessage;
}
}
Any request to any URL below http://myhost/ will automatically be sent this cookie.

Resources