Response cookies using for next requests - cookies

As I see from the answer for this question: Karate will automatically send any cookies returned by the server in the next request.
But when I send the request I see two sets of cookies in Set-Cookie of response: one is auto-created and another is real, that returned from the server.
When I printed responseCookies, I saw there only automatic cookies
and for the next request new cookies are generated and sent.
For my test I need to use cookies returned after the first request because it is a call to login service.
Feature: Using cookies in next request
Background:
Given url baseUrl
And path LOGOUT_SERVICE_ENDPOINT
And configure headers = read('classpath:headers.js')
And def filename = 'classpath:resources/users/' + brand.toLowerCase() + '/user.json'
And json user = read(filename)
Scenario: Login
When def login = callonce read('classpath:features/login_service/login.feature') user
* print login.responseCookies
And request { arg1: '#(brand)'}
And method post
Then status 200
What is wrong in my feature or it is Karate issue?

two sets of cookies in Set-Cookie of response:
Maybe that is a bug in the server ?
Also try using "shared scope", because cookies also will be part of the "global" variables etc.
* callonce read('classpath:features/login_service/login.feature') user
* request { arg1: '#(brand)'}
If you are still stuck, please follow this process: https://github.com/intuit/karate/wiki/How-to-Submit-an-Issue

Related

Does anyone know how to send API calls to an application using a __RequestVerificationToken? (Error: The cookie and the form field were swapped)

I'm trying to test out Anti Forgery tokens with API calls using VS2019 (C#) and RestSharp. What i'm doing is doing a GET to our login page to get 4 tokens/ cookies, then attaching these to a POST, with the Username and password, to try to log on. The first call succeeds and gives me a HTTP 200 and 4 cookies/ tokens back (ASP.NET_SessionId, XSRF-TOKEN, XSRF-COOKIE and a __RequestVerificationToken - all get attached as cookies (in the cookiecontainer) to the POST API call), the 2nd call however, fails with an HTTP 500 with this message: "Validation of the provided anti-forgery token failed. The cookie "__RequestVerificationToken" and the form field "__RequestVerificationToken" were swapped.". I'm including this token twice in my POST call - once as a cookie and once as part of the request body. Here is my code - can anyone shed any light on how to fix this error?
Thanks,
Jamie.
public void LogIn(string userName, string password)
{
// 1st call to get the cookies and tokens.
CommonProperties.Client = new RestClient { CookieContainer = new CookieContainer() };
CommonProperties.Client.BaseUrl = new Uri($"https://localhost:50000/Account/Login");
var request = new RestRequest(Method.GET);
request.AddParameter("ReturnUrl", "%2F", ParameterType.QueryString);
CommonProperties.Response = CommonProperties.Client.Execute(request);
CommonProperties.Client.BaseUrl = new Uri($"https://localhost:50000/Account/Login");
var requestToken = CommonProperties.Response.Cookies.Single(c => c.Name ==
"__RequestVerificationToken");
// 2nd call to log in.
request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddHeader("Accept-Encoding", "gzip, deflate, br");
request.AddHeader("Accept", "*/*");
request.AddHeader("Referer", $"https://localhost:50000/Account/Login");
request.AddParameter("undefined", $"__RequestVerificationToken=
{requestToken.Value}&UserName=userName&Password=password_321", ParameterType.RequestBody);
CommonProperties.Response = CommonProperties.Client.Execute(request);
}
I just solved this issue myself, so hopefully this answer helps anyone else who comes looking.
When you originally load the page with the GET it will return the cookie with the name of __RequestVerificationToken PLUS a form field with the same name. That form field will have a different value to the cookie's value, and in your POST you must set the body field for __RequestVerificationToken to have that form field's value, and the value of the cookie with the same name must match the cookie from the GET response.
If you have the same value for both the form field and the cookie, you get that rather misleading error that suggests the values are "swapped". They are not actually swapped, they're just matching, which is incorrect.

How to access the value of a cookie injected in the request header on a POST call using Lua?

I'm attempting to retrieve an authentication cookie from a POST sign-in request. When I send this request using Postman, I see the cookie's value in the Cookies tab of the response in Postman.
Postman Response Cookies
My current Lua script is as follows:
local signInUrl = webBaseUrl.."/signin"
local signInResponse = http.request({"POST", signInUrl, headers={
["Content-Type"]="application/x-www-form-urlencoded",
["Referer"] = baseUrl}, data="UrlHash=&UserName="..username.."&Password=123&RememberMe=false", auto_decompress=true})
for i,v in pairs(signInResponse.cookies) do print(i,v) end
Printing out the value of the cookies returns a sessionId cookie and a return email cookie, but not the authentication cookie that I'm looking for.
I can see that the authentication cookie that I'm looking for is actually located in the Request Headers, in the Postman Console.
Postman Console
How would I go about getting the value of this cookie?

How to get request body of XMLHttpRequest (XHR) using Python (Ghost.py)?

I am trying to load a web page and monitor it for XHR (XMLHttpRequests). To do this I am using Ghost.py with Python2.7. I can see the XHR being made and can read the URL and response, however I would like to read the request body so that I can recreate these requests at a later date.
from ghost import Ghost, Session
ghost = Ghost()
with ghost.start():
session = Session(ghost, download_images=False, display=False)
page, rs = session.open("https://www.example.com/", timeout=60)
assert page.http_status == 200
result, resources = session.wait_while_selector('[class=loading]:not([style="display: none;"])', timeout=60)
for resource in resources:
print resource.url
print resource.content
I have searched within the documentation, but cannot find any references to XHR request body and I have searched within the returned resources object for references to the request, but can only find request.headers (which does not include the POST body) and the _reply data.
Can you save the POST body of a XHR request as well as the response?

Django: why CSRF_COOKIE in request.META

I used requests to send request.
import requests
def print(req):
print('{}\n{}\n{}\n\n{}'.format(
'-----------START-----------',
req.method + ' ' + req.url,
'\n'.join('{}: {}'.format(k, v) for k, v in req.headers.items()),
req.body,
))
print "----------END------------"
try:
req = requests.Request('GET',
'https://myip/myproject/upload/token',
headers={'Authorization': 'Token 401f7ac837a',
})
prepared = req.prepare()
print(prepared)
except Exception as e:
print "Exception:", e
Output:
-----------START-----------
GET https://myip/myproject/upload/token
Authorization: Token 401f7ac837a
None
----------END------------
But after I printed the request.META, there is
META:{u'CSRF_COOKIE': u'YGzoMaNEQJz1Kg8yXAwjJt6yNuT9L'
What set the CSRF_COOKIE?
Any comments welcomed. Thanks
UPDATE
(1)
From the doc, it said This cookie is set by CsrfViewMiddleware, which means the CSRF cookie was set in back-end and set to front-end in the response (CSRF cookie: server -> browser). Why it also said For all incoming requests that are not using HTTP GET, HEAD, OPTIONS or TRACE, a CSRF cookie must be present? And why it appears in my request.META? (CSRF cookie: browser -> server ???)
(2)
It said **A hidden form field with the name ‘csrfmiddlewaretoken’ present in all outgoing POST forms. The value of this field is the value of the CSRF cookie.
This part is done by the template tag.
**
When and How the template tag do it?
This is a standard cookie Django applications spin up for each new user to prevent Cross Site Forgery.
A CSRF cookie that is set to a random value (a session independent
nonce, as it is called), which other sites will not have access to.
This cookie is set by CsrfViewMiddleware. It is meant to be permanent,
but since there is no way to set a cookie that never expires, it is
sent with every response that has called
django.middleware.csrf.get_token() (the function used internally to
retrieve the CSRF token).
For security reasons, the value of the CSRF cookie is changed each
time a user logs in.
for more reading
https://docs.djangoproject.com/en/1.9/ref/csrf/#how-it-works

HTTPOnly Cookie not being stored before redirect

Currently, I have an HTML page that sends a POST request to a Python server with login details. The Python server verifies the login and then sends back a cookie via headers (I'm using the Cookie class built into the Python library). I want to redirect as soon as I get a 200 OK status. The issue is that the cookies are not being set quickly enough, so the redirect happens before the cookies are set and thus the check_login page will display that I have not logged in.
I want the browser to store an HTTPOnly cookie. Is there something in the XMLHttpRequest API that will let me redirect after the cookie has been stored, or an alternative method?
Thanks!
The HTTPRequest code:
var httpRequest = new XMLHttpRequest();
var url = 'http://localhost/login/';
httpRequest.onreadystatechange = function(){
if (httpRequest.readyState == 4) {
if(httpRequest.status == 200) {
window.location = "http://localhost/check_login/";
}
};
httpRequest.open("POST", url,false);
httpRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded");
httpRequest.send(/*login details*/);
This request is called by clicking a button. If I go back to the page that this button is on and then click it again, I will always be logged in because the cookie was already set from the first click.