I am using jwt to authorize users on a react app I am working on. As opposed to using localStorage or sessionStorage to store these tokens, I am sending httpOnly, sameSite: strict, secure cookies as shown.
res
.cookie("jwt-access", accessToken, {
httpOnly: true,
sameSite: "strict",
secure: true,
})
.cookie("jwt-refresh", refreshToken, {
httpOnly: true,
sameSite: "strict",
secure: true,
})
.json({ error: false, response: "Authorized" });
My app is successfully able to communicate with my api using the access and refresh tokens while hosted on the same domain as the api server (www.example.com/app, www.example.com/api).
If I understand correctly the react development server is hosted on an http server running on port 3000. Because this server is considered to be running on a different and unsecure domain, these secure cookies are not able to be properly communicated. I thought reconfiguring these cookies to secure: false and sameSite: "none" would have allowed these cookies to be correctly communicated but it hasn't.
Why is it that these updated cookies are unable to be sent/received with the development server and what can I do to properly configure them?
If its any use, here is the request header from each server:
Production server correctly receives cookies
[Symbol(kHeaders)]: {
host: 'localhost:446',
connection: 'close',
'sec-ch-ua': '"Google Chrome";v="107", "Chromium";v="107", "Not=A?Brand";v="24"',
accept: 'application/json, text/plain, */*',
'sec-ch-ua-mobile': '?0',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-site': 'same-origin',
'sec-fetch-mode': 'cors',
'sec-fetch-dest': 'empty',
referer: 'https://zyae.net/',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'en-US,en;q=0.9',
cookie: 'jwt-access=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYzODJkOWNjYTMwMDM2N2NkOGZlZGZiZiIsImlhdCI6MTY2OTU5ODg4MiwiZXhwIjoxNjY5NTk5NDgyfQ.bYSN7jJwuL2UyLpu3rModl5HAQ7FQ8R7sQUDEOq7Z0g; jwt-refresh=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYzODJkOWNjYTMwMDM2N2NkOGZlZGZiZiIsImlhdCI6MTY2OTU5ODg4Mn0.gv4BycPhBlEXOc6TLYj6w07diAQ0hOBQT03tTNfF9Hs',
'if-none-match': 'W/"9c-GSJl0bJ1H5bULPZaYoSPi1M3gMw"'
}
Development server
[Symbol(kHeaders)]: {
host: 'localhost:446',
connection: 'close',
pragma: 'no-cache',
'cache-control': 'no-cache',
'sec-ch-ua': '"Google Chrome";v="107", "Chromium";v="107", "Not=A?Brand";v="24"',
accept: 'application/json, text/plain, */*',
'sec-ch-ua-mobile': '?0',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36',
'sec-ch-ua-platform': '"Windows"',
origin: 'http://zyae.net:3000',
'sec-fetch-site': 'cross-site',
'sec-fetch-mode': 'cors',
'sec-fetch-dest': 'empty',
referer: 'http://zyae.net:3000/',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'en-US,en;q=0.9'
}
Related
i have multiple files which is HTTP request in json file format and every file content as following .
{
"http://testphp.vulnweb.com/search.php": {
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "en-US,en;q=0.5",
"Connection": "close",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:83.0) Gecko/20100101 Firefox/83.0"
},
"method": "POST",
"params": [
"goButton",
"searchFor"
]
}
}%
desired output is raw request as following
POST /search.php HTTP/1.1
Host: testphp.vulnweb.com
Content-Length: 23
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.30
Connection: close
searchFor=a&goButton=go
and BTW the default char in the end of lines is \r\n as it the default format of HTTP raw request and there is extra \r\n in the line before parameters.
i really don`t know if awk could handle this or not but if it how hard it will be??
plz also recommend any online solution to do so if i have to go that way because i struggling in search for reformat from json to raw request.
Thanks
I am trying to log in to the pge.com website using Google Apps Scripts, with my username and password, so that I can retrieve my electricity consumption details. The need is similar to this thread
I have inspected network calls during login but I cannot figure out how my username and password are passed.
I can see two subsequent calls to the login service.
First request (doesn't seem to carry a payload):
**General**
Request URL: https://apigprd.cloud.pge.com/myaccount/v1/login?ts=1614544850626
Request Method: OPTIONS
Status Code: 200 OK
Remote Address: 130.19.47.120:443
Referrer Policy: strict-origin-when-cross-origin Response Headers
** Response Headers **
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: authorization
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Origin: https://www.pge.com
Content-Encoding: gzip
Content-Length: 59
Content-Type: text/plain;charset=UTF-8
Date: Sun, 28 Feb 2021 20:40:50 GMT
Set-Cookie: TS01ef76cb=015399e11<...>dc1f; Path=/; Domain=.apigprd.cloud.pge.com
X-Tracking-ID
X-Transaction-ID: 00000177b2ec4203-10baebc
** Request Headers **
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Access-Control-Request-Headers: authorization
Access-Control-Request-Method: GET
Connection: keep-alive
Host: apigprd.cloud.pge.com
Origin: https://www.pge.com
Referer: https://www.pge.com/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36
A subsequent request is then made:
** General **
Request URL: https://apigprd.cloud.pge.com/myaccount/v1/login?ts=1614544850626
Request Method: GET
Status Code: 200 OK
Remote Address: 130.19.47.120:443
Referrer Policy: strict-origin-when-cross-origin
** Response Headers **
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers
Access-Control-Allow-Origin: https://www.pge.com
Content-Encoding: gzip
Content-Length: 101
Content-Type: application/json;charset=UTF-8
Date: Sun, 28 Feb 2021 20:40:50 GMT
set-cookie: PF=cuLZ7Vh4y6keKdWEzXVaxD4kzuePT0wcOOyvxZ6V3u0K; Path=/; Domain=.cloud.pge.com; Secure; HttpOnly
set-cookie: PA.ToI.CustomerWeb=eyJhb<...>MifQ..8p6<...>iqw.1BewS--tpmP<...>3fo-rbtoh-<...>Egz-acEIN58H-dO<...>rWR-Q<...>w; Path=/; Domain=pge.com; Secure; HttpOnly
Set-Cookie: TS01ef76cb=015399e11<...>ec2d9; Path=/; Domain=.apigprd.cloud.pge.com
Set-Cookie: TS01d056a5=015399e11<...>2fc17; path=/; domain=pge.com
X-Tracking-ID
X-Transaction-ID: 0000017602681258-9359011
** Request Headers **
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Authorization: Basic bWFy<...>wc2U=
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Cookie: optimizelyEndUserId=oeu1<...>2r0.2464<....>336; oo_inv_percent=0; _gcl_au=1.1.1250622131.1614535637; AMCVS_DF70BB6B55BA62677F000101%40AdobeOrg=1; s_cc=true; _ga=GA1.2.676<...>72.1614535638; _gid=GA1.2.127<...>54.1614535638; _fbp=fb.1.1614535638419.135544411; userLanguageSelected=English; com.silverpop.iMAWebCookie=654ee074-<...>-<...>-0784-4940b13c1dc8; CARE_LANG=English; BIGipServer~Prod~P-itiampingaccess.cloud.pge.com-pool=1796742666.54795.0000; com.silverpop.iMA.session=2764a7b2-1c77-<...>-<...>-b56816c03631; com.silverpop.iMA.page_visit=2144181430:; s_sq=%5B%5BB%5D%5D; PF=dyxdIf<...>wnCDfDTC4EeNVNzFtF3; care_hashed_acct_id=811067339<...>E559C253; PGE_EN=4nx9s6<...>NigxfgqMgNTc/Hs7mt6oL<...>M3oG2lGBv+FNpQhj4U1N8YVv<...>TEUP1x9NU5QJQPcImd/s3FVCFgLy<...>qhrhuv+HQ1J/OANiGah+0exaD2ScPRBd3MQ/+4EqtzOEbpsjjKDKN<...>qe+mOMjkjZ0otbEknx5I7Z1p8w/KxI0fvwT32RBc5U+92j6CxxIDoYwm3KlmCQ==; TS01d056a5=015399e11<...>e65810; TS01ef76cb=015399e11<...>73b336; ADRUM=s=1614544835448&r=https%3A%2F%2Fm.pge.com%2Findex.html%3F35; oo_OODynamicRewrite_weight=0; oo_inv_hit=3; AMCV_DF70BB6B55BA62677F000101%40AdobeOrg=-1303530583%7C<...>Bpb2zX5dvJdYQJzPXImdj0y%7CMCOPTOUT-1614552037s%7CNONE%7CMCAID%7CNONE%7CMCSYNCSOP%7C411-18694%7CvVersion%7C3.3.0; OptanonConsent=isIABGlobal=false&datestamp=Sun+Feb+28+2021+12%3A40%3A37+GMT-0800+(Pacific+Standard+Time)&version=6.1.0&consentId=749474e8-c692-470b-be09-77aa32646232&interactionCount=0&landingPath=NotLandingPage&groups=C0001%3A1%2CC0002%3A1%2CC0003%3A1%2CC0004%3A1%2CC0005%3A1&hosts=&legInt=&AwaitingReconsent=false; _dc_gtm_UA-64722139-1=1; _gat_UA-77056718-1=1; s_tp=2617; s_ppv=PG%2526E%252C%2520Pacific%2520Gas%2520and%2520Electric%2520-%2520Gas%2520and%2520power%2520company%2520for%2520California%2C35%2C35%2C914; s_plt=3.13; utag_main=v_id:0177e9d2<...>78001407000ac8$_sn:2$_ss:1$_st:1614546650462$vapi_domain:pge.com$dc_visit:8$_pn:1%3Bexp-session$ses_id:1614544836893%3Bexp-session$dc_event:2%3Bexp-session$dc_region:us-east-1%3Bexp-session
Host: apigprd.cloud.pge.com
Origin: https://www.pge.com
Referer: https://www.pge.com/
sec-ch-ua: "Chromium";v="88", "Google Chrome";v="88", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36
How can I use the Google Apps Script to login?
PS I have tried the following:
function loginPge() {
var baseUrl = "https://apigprd.cloud.pge.com/myaccount/v1/login";
var now = Date.now();
var url = baseUrl + '?ts=' + now;
var payload =
{
"username" : "xxx",
"password" : "xxx",
};
var headers =
{
"Accept":"*/*",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "en-US,en;q=0.9",
"Access-Control-Request-Headers": "authorization",
"Access-Control-Request-Method": "GET",
"Connection": "keep-alive",
"Origin": "https://www.pge.com",
"Referer": "https://www.pge.com/",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-site",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36"
};
var options =
{
"headers":headers,
"method" : "get",
"payload" : payload,
"followRedirects" : false
};
var login = UrlFetchApp.fetch(url, options);
return;
}
But I am getting an error message
Exception: Request failed for https://apigprd.cloud.pge.com returned
code 400. Truncated server response: {"user": "unknown",
"errorCode":"33"}
I am a little late, but maybe it helps someone else.
The username and password are sent in 'Authorization' header. I figured out the value for this header by inspecting the login page source where it appears as:
<set-header value="Basic base64($username:$password)" name="Authorization"></set-header>
Below is Python code to login and get user details:
import requests
import base64
username = 'test'
password = 'test'
session = requests.Session()
auth = ':'.join([username, password]).encode('utf8')
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:88.0) Gecko/20100101 Firefox/88.0',
'Accept': '*/*',
'Accept-Language': 'en-US,en;q=0.5',
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic {}'.format(
base64.b64encode(auth).decode('utf8')
),
'Origin': 'https://www.pge.com',
'Connection': 'keep-alive',
'Referer': 'https://www.pge.com/',
}
resp = session.get(
'https://apigprd.cloud.pge.com/myaccount/v1/login',
headers=headers
)
print(resp.json()) # get the json response
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:88.0) Gecko/20100101 Firefox/88.0',
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Language': 'en-US,en;q=0.5',
'Content-Type': 'application/json',
'X-RAS-API-USERKEY': 'pgecocmobile',
'cocGUID': 'null',
'Origin': 'https://m.pge.com',
'Connection': 'keep-alive',
'Referer': 'https://m.pge.com/',
}
params = (
('userId', username),
)
resp = session.get(
'https://apigprd.cloud.pge.com/myaccount/v1/cocaccount/secure/account/retrieveMyEnergyAccounts',
params=params, headers=headers
)
print(resp.json()) # get the json response with acc details
Access to XMLHttpRequest from has been blocked by CORS policy: Response to preflight request doesn't pass
access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
My CORS configuration:
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"PUT",
"POST",
"GET",
"DELETE"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": [
"ETag",
"x-amz-server-side-encryption",
"x-amz-request-id",
"x-amz-id-2",
"Content-Length",
"Content-Type",
"Connection",
"Date",
"x-amz-version-id",
"Server"
],
"MaxAgeSeconds": 10
}
]
Request headers:
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7
Access-Control-Request-Headers: authorization,content-type,x-amz-content-sha256,x-amz-date,x-amz-
user-agent
Access-Control-Request-Method: POST
Cache-Control: no-cache
Connection: keep-alive
Host: s3.amazonaws.com
Origin: http://localhost:8080
Pragma: no-cache
Referer: http://localhost:8080/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/86.0.4240.111 Safari/537.36
It was trying to reach a wrong region as I didn't specify one
I am getting following error wile doing axios post request.
But when I use ajax request there is no issue:
request has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Ajax Request:
Axios request:
let payload = {
type: ["a", "b"],
category: ["a", "b"],
category: ["a", "b"],
accountNumber: "123"
};
var apiURL = this.$apiBaseURL + "/Product/ProductDetails";
$.ajax({
url: apiURL,
type: "POST",
data: { payload },
xhrFields: {
withCredentials: true
},
success: function (result) {
console.log(JSON.stringify(result));
}
});
this.$http.post(apiURL,payload,{withCredentials: true})
**UPDATE 1 **
I am still facing the same issue. Here I will share the request header in both ajax and axios request
AJAX Working code and request header :
{
var apiURL = this.$apiBaseURL + "/Request/MediaUpload";
$.ajax({
method: 'post',
processData: false,
contentType: false,
cache: false,
data: fileformData,
enctype: 'multipart/form-data',
url: apiURL,
xhrFields: {
withCredentials: true
}
});
}
Request header:
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Content-Length: 7610
Content-Type: multipart/form-data; boundary=----
WebKitFormBoundaryAjc8HwVPaRtQ5Iby
Host: localhost:62148
Origin: http://localhost:8989
Referer: http://localhost:8989/
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36
AXIOS failing code and header
var apiURL = this.$apiBaseURL + "/Request/MediaUpload";
var self=this;
let config={
headers:{
'Content-Type': 'multipart/form-data'
}
}
this.$http.post(apiURL, { withCredentials: true },fileformData,
config)
Request Headers:
Provisional headers are shown
Accept: application/json, text/plain, */*
Content-Type: application/json;charset=UTF-8
Referer: http://localhost:8989/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36
Here is my web api config where I have enabled cors
string origin = "http://localhost:8989";
EnableCorsAttribute cors = new EnableCorsAttribute(origin, "*", "*", "*");
cors.SupportsCredentials = true;
config.EnableCors(cors);
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
**UPDATE 2 **
The CORS configuration at server side is done correctly thats why I am able to make the call successfully via AJAX.
Is this a known AXIOS issue which occurs only when we enable the windows authentication?
This issue arises because jQuery sends the request as application/x-www-form-urlencoded by default and does not send preflight request whereas axios sends as application/json and sends a preflight request i.e. OPTIONS before sending actual request.
One way it could work is by setting Content-type header to 'Content-Type': 'application/x-www-form-urlencoded' in axios.
You will have to change the settings on server side to get around this issue.
Add this in your web.config file:
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
Using default ajax won't send any OPTIONS request, but using axios does. This will enable accepting OPTIONS requests.
After hours of digging and testing i got my local frontent (angular2) to speak with a dev backend.
Using withCredentials: true on https request and htaccess:
Header add Access-Control-Allow-Origin "https://127.0.0.1:3000"
Header add Access-Control-Allow-Credentials "true"
Header add Access-Control-Allow-Methods "GET, POST"
It's all fine until i reload the page - and i have to login again.
This is sent with requests, but cookie PHPSESSID is not actually saved on disk:
Cookie:PHPSESSID=jp65lr9tviq6n5q9s1i0fupuq7
If i build the code and upload to the same server where backend is, not using CORS - it all works fine, but i cannot do that when i develop frontend locally.
Response Headers:
Access-Control-Allow-Credentials:true
Access-Control-Allow-Methods:GET, POST
Access-Control-Allow-Origin:https://127.0.0.1:3000
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:105
Content-Type:text/html
Date:Tue, 04 Apr 2017 14:15:56 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive:timeout=5, max=100
Pragma:no-cache
Server:Apache/2.4.7 (Ubuntu)
Vary:Accept-Encoding
X-Powered-By:PHP/5.5.9-1ubuntu4.20
Request Headers:
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-GB,en;q=0.8
Connection:keep-alive
Content-Length:62
Content-Type:application/x-www-form-urlencoded
Cookie:PHPSESSID=cjoe07094u4139i7c0pb4cd3e7
Host:dev.server.com
Origin:https://127.0.0.1:3000
Referer:https://127.0.0.1:3000/login
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
What am i missing here?
UPDATE:
It seems like it does save it - under wrong domain. The cookie is set under the api server domain and localhost cannot find it anymore.
Setting up a proxy in webpack settings:
proxy: {
'/authenticate': {
target: 'https://dev.server.com',
secure: false,
changeOrigin: true
},
'/Api': {
target: 'https://dev.server.com',
secure: false,
changeOrigin: true
}
}
Together with withCredentials: true got around the issue.