I have a question, I do not understand why the cookie is not added. I have a frontend and backend on separate servers and at various ports, I hit the backend for a token. In response, he gets it, however, it is not set. Could someone look? Secure and httpOnly is deactivated. On the frontend side I have set withCredentials: true.
On the frontend side:
axios.defaults.withCredentials = true;
axios.post('http://backendhost:8584/login', user).then(response => {
if(response){
this.props.history.push('/home');
}
});
Cors On the api side:
#Bean
CorsConfigurationSource corsConfiguration() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.setAllowedOrigins(Collections.singletonList("*"));
config.setAllowedMethods(Collections.singletonList("*"));
config.setAllowedHeaders(Collections.singletonList("*"));
UrlBasedCorsConfigurationSource source =
new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
Set cookie on the auth server side:
response.addCookie(generateCookie("session-token", customer.getToken()));
public Cookie generateCookie(String key, String value) {
Cookie cookie = new Cookie(key,value);
cookie.setMaxAge(60 * 60 * 24 * 365);
cookie.setSecure(false);
cookie.setHttpOnly(false);
cookie.setPath("/");
return cookie;
}
And I get it in chrome:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://frontendhost:8080
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: application/json
Date: Tue, 16 Jun 2020 16:30:11 GMT
Expires: 0
Pragma: no-cache
Referrer-Policy: no-referrer
Set-Cookie: session-token=eyJhbGciOiJSUz; Max-Age=31536000; Expires=Wed, 16-Jun-2021 16:30:11 GMT; Path=/
transfer-encoding: chunked
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Related
i am trying to send a synchronized request to https server with esp8266 and i am using httpbin.org for testing purpose and i want to synchronize the requests. i mean how to not sending request until the previous is recieved and without using delay?
by comparing code (below) and result (below) you can see that httpsClient.readString() returns empty result from time to time. why? how to explain that? and how to fix that or get around it?
code and result are bellow. please help.
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
//i cut wifi ssid and pswrd declaration to shorten the question
const char *host = "httpbin.org"; //Domain to Server
String path = "/post"; //Path of Server
const int httpsPort = 443; //HTTPS PORT (default: 443)
WiFiClientSecure httpsClient;
String response;
void setup() {
//i cut wifi set up declaration to shorten the question
httpsClient.setInsecure();
if(httpsClient.connect(host, httpsPort)){
Serial.println("Connected to "+String(host));
}else
Serial.println("error connecting");
}
void loop() {
httpsClient.print(String("POST ") + "/response-headers" + " HTTP/1.1\r\n" +
"Host: " + "httpbin.com\r\n"+
"Content-Type: application/x-www-form-urlencoded\r\n" +
"Content-Length: 13\r\n\r\n" +
"say=Hi&to=Sam\r\n");
while(httpsClient.available()) {
response = httpsClient.readStringUntil('\n');
Serial.println(response);
}
Serial.println("---------------------------------------------------------");
}
Result:
---------------------------------------------------------
HTTP/1.1 200 OK
Date: Wed, 26 May 2021 16:20:01 GMT
Content-Type: application/json
Content-Length: 68
Connection: keep-alive
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
{
"Content-Length": "68",
"Content-Type": "application/json"
}
---------------------------------------------------------
---------------------------------------------------------
HTTP/1.1 200 OK
Date: Wed, 26 May 2021 16:20:01 GMT
Content-Type: application/json
Content-Length: 68
Connection: keep-alive
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
{
"Content-Length": "68",
"Content-Type": "application/json"
}
HTTP/1.1 200 OK
Date: Wed, 26 May 2021 16:20:01 GMT
Content-Type: application/json
Content-Length: 68
Connection: keep-alive
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
{
"Content-Length": "68",
"Content-Type": "application/json"
}
---------------------------------------------------------
HTTP/1.1 200 OK
Date: Wed, 26 May 2021 16:20:02 GMT
Content-Type: application/json
Content-Length: 68
Connection: keep-alive
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
{
"Content-Length": "68",
"Content-Type": "application/json"
}
---------------------------------------------------------
---------------------------------------------------------
---------------------------------------------------------
---------------------------------------------------------
---------------------------------------------------------
---------------------------------------------------------
HTTP/1.1 200 OK
Date: Wed, 26 May 2021 16:26:19 GMT
Content-Type: application/json
Content-Length: 68
Connection: keep-alive
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
{
"Content-Length": "68",
"Content-Type": "application/json"
}
and so on.....
I am trying to send the Alert/Remainder via POSTMan to my skill.
Option 1: Authentication token API with Scope "alexa:skill_messaging"
POST /auth/o2/token HTTP/1.1
Host: api.amazon.com
Content-Type: application/x-www-form-urlencoded
User-Agent: PostmanRuntime/7.20.1
Accept: */*
Cache-Control: no-cache
Postman-Token: 2ae7afa3-c3f8-493f-b6e3-2db1e44e3a17,a4e45e8e-d0eb-4b3f-a612-e7d1959fdbe6
Host: api.amazon.com
Accept-Encoding: gzip, deflate
Content-Length: 236
Connection: keep-alive
cache-control: no-cache
grant_type=client_credentials&client_id=******************&client_secret=***********17a4f7b348982bdb4&scope=alexa%3Askill_messaging
Screenshote:
option 2: Authentication token API with Scope "alexa::alerts:reminders:skill:readwrite"
POST /auth/o2/token HTTP/1.1
Host: api.amazon.com
Content-Type: application/x-www-form-urlencoded
User-Agent: PostmanRuntime/7.20.1
Accept: */*
Cache-Control: no-cache
Postman-Token: 2ae7afa3-c3f8-493f-b6e3-2db1e44e3a17,c6765f77-6e35-419f-b614-780dae20ad4e
Host: api.amazon.com
Accept-Encoding: gzip, deflate
Content-Length: 236
Connection: keep-alive
cache-control: no-cache
grant_type=client_credentials&client_id=**************************&client_secret=************************&scope=alexa%3A%3Aalerts%3Areminders%3Askill%3Areadwrite
Step 2: Submitting the Alert request using token generated by Scope "alexa:skill_messaging" getting Invalide Bearer token
Let me know if I am missing anything and also where can find different scope for Alexa Authenictaion Token API
Unfortunately,
"That's a limitation of the Reminders API - you need to use the in-session access token to create reminders. You can run GET, UPDATE and DELETE operations out of session as well, so check this out for more information."
Only speaking with the device is possible get in-session access token to create reminders.
Out-session - Get reminders created by the skill (Skill Messaging API):
const IncomingMessageHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'Messaging.MessageReceived'
},
async handle(handlerInput) {
const { requestEnvelope, context } = handlerInput;
console.log(`Message content: ${JSON.stringify(requestEnvelope.request.message)}`);
try {
const client = handlerInput.serviceClientFactory.getReminderManagementServiceClient();
const remindersResponse = await client.getReminders();
console.log(JSON.stringify(remindersResponse));
} catch (error) {
console.log(`error message: ${error.message}`);
console.log(`error stack: ${error.stack}`);
console.log(`error status code: ${error.statusCode}`);
console.log(`error response: ${error.response}`);
}
context.succeed();
}
}
https://developer.amazon.com/docs/smapi/alexa-reminders-api-reference.html#in-session-and-out-of-session-behavior-for-alexa-reminders-api
https://forums.developer.amazon.com/questions/196445/reminders-can-only-be-created-in-session.html#answer-196860
https://developer.amazon.com/pt-BR/docs/alexa/smapi/skill-messaging-api-reference.html
This is edited from original post:
From the docs:
Signing a Message The CB-ACCESS-SIGN header is generated by creating a
sha256 HMAC using the base64-decoded secret key on the prehash string
timestamp + method + requestPath + body (where + represents string
concatenation) and base64-encode the output. The timestamp value is
the same as the CB-ACCESS-TIMESTAMP header.
Here is information from a key I deleted. This is from Coinbase Pro Sandbox:
publicKey:
06057d5b5e03d0f8587a248330402b21
passPhrase:
gcgs6k6rp0f
secretKey: EFAToD5heo66GIgZlT2TIZzJf8TYlmxyeRxRYDHTBv3lTt9XN6uaNS0RNAy0os/caR47x6EiPDOV3Ik+YzrfEA==
I'm using angular, specifically the node.js crypto-js library:
private generateSignaturePro(timestamp: string, method: string, resourceUrl: string, requestBody: string): string {
var prehash: string = timestamp + method + resourceUrl + requestBody;
var key = (Buffer.from(this.secretKey, 'base64')).toString();
return crypto.enc.Base64.stringify(crypto.HmacSHA256(prehash, key));
}
Server time is Time: 2019-05-20T19:01:38.711Z Epoch: 1558378898.711 (from /time endpoint)
here is my request and the server response:
Request:
Request URL: https://api-public.sandbox.pro.coinbase.com/accounts
Request Method: GET
Status Code: 400
Remote Address: 104.16.161.226:443
Referrer Policy: no-referrer-when-downgrade
Request Headers:
Provisional headers are shown
Accept: application/json, text/plain, */*
CB-ACCESS-KEY: 06057d5b5e03d0f8587a248330402b21
CB-ACCESS-PASSPHRASE: gcgs6k6rp0f
CB-ACCESS-SIGN: 0cc2BnQYdUhLucXSPwMTjpHjJ32G3RXSH44rSsEopvjAtY90uRCMVy6xUrzg/A/aRJBLqx390fcZc7lmJeP++g==
CB-ACCESS-TIMESTAMP: 1558378899
Referer: https://localhost:44342/dashboard
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36
Response Headers:
access-control-allow-headers: Content-Type, Accept, cb-session, cb-fp
access-control-allow-methods: GET,POST,DELETE,PUT
access-control-allow-origin: *
access-control-expose-headers: cb-before, cb-after, cb-gdpr
access-control-max-age: 7200
cache-control: no-store
cf-cache-status: MISS
cf-ray: 4da08f74ba97cf68-IAD
content-length: 31
content-type: application/json; charset=utf-8
date: Mon, 20 May 2019 19:01:38 GMT
etag: W/"1f-4RjKVp8I05+xcnQ5/G16yRoMSKU"
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
status: 400
strict-transport-security: max-age=15552000; includeSubDomains
vary: Accept-Encoding
x-content-type-options: nosniff
x-dns-prefetch-control: off
x-download-options: noopen
x-frame-options: SAMEORIGIN
x-xss-protection: 1; mode=block
Response:
{"message":"invalid signature"}
What am I doing wrong?
EDIT: Changed method to the SHA 256 version. Still doesn't work.
I ran into same issue and my code was same as yours basically. I changed to the following (c#) and it finally worked. Weird thing is coinbase pro is only exchange i have had issues with so far with the signature. In any case here is the code that worked for me. Hope this helps. Would have saved me hours
public string ComputeSignature(
HttpMethod httpMethod,
string secret,
double timestamp,
string requestUri,
string contentBody = "")
{
var convertedString = System.Convert.FromBase64String(secret);
var prehash = timestamp.ToString("F0", CultureInfo.InvariantCulture) + httpMethod.ToString().ToUpper() + requestUri + contentBody;
return HashString(prehash, convertedString);
}
private string HashString(string str, byte[] secret)
{
var bytes = Encoding.UTF8.GetBytes(str);
using (var hmaccsha = new HMACSHA256(secret))
{
return System.Convert.ToBase64String(hmaccsha.ComputeHash(bytes));
}
}
From the gdax-java (as it was named prior to "coinbase pro") library the generate signature method is:
String prehash = timestamp + method.toUpperCase() + requestPath + body;
byte[] secretDecoded = Base64.getDecoder().decode(secretKey);
keyspec = new SecretKeySpec(secretDecoded, "HmacSHA256");
sha256 = (Mac) GdaxConstants.SHARED_MAC.clone();
sha256.init(keyspec);
return Base64.getEncoder().encodeToString(sha256.doFinal(prehash.getBytes()));
At least on initial inspection the code you're using specifies using SHA512 rather than HmacSHA256, so I'd suspect that to be a probabale cause.
There is also more help with NodeJS in the right hand column here for generating the signatures. https://docs.pro.coinbase.com/#creating-a-request
Had the same issue here. For me the answer was to use luxon DateTime instead of the native js Date functions as shown in the coinbase docs.
Here is the typescript that works for me. You can use the results of this function to populate your request headers.
import crypto from 'crypto';
import { DateTime } from 'luxon';
export const auth = (
method: 'GET' | 'POST',
path: string,
body?: Record<string, unknown>
) => {
const timestamp = DateTime.utc().toMillis() / 1000;
let message = timestamp + method + path;
if (body) {
message += JSON.stringify(body);
}
const secret = Buffer.from('YOUR_SECRET','base64');
const hmac = crypto.createHmac('sha256', secret);
return {
'CB-ACCESS-KEY': 'YOUR_KEY',
'CB-ACCESS-PASSPHRASE': 'YOUR_PASSPHRASE',
'CB-ACCESS-SIGN': hmac.update(message).digest('base64'),
'CB-ACCESS-TIMESTAMP': timestamp.toString()
};
};
my draft with big Attachment.
create draft with gapi.
update this draft add some big file.
upload draft rawdata by resumable upload.
when i start a resumable session, it return 404.
Array
(
[url] => https://www.googleapis.com/resumable/upload/gmail/v1/users/me/drafts/r3718017142990379914
[method] => post
[http_header] => Array
(
[0] => Authorization: Bearer ya29.****
[1] => Content-type: application/json
[2] => X-Upload-Content-Type: message/rfc822
)
[response] => HTTP/1.1 200 Tunnel established
HTTP/1.1 404 Not Found
X-GUploader-UploadID: AEnB2Up-CJW9XP4E84DqWjZhI_8-YFgWR47UNNfqGkmM2S5EBf3H5aGOcuwHzLd-4faoKAxd_qgaO5GInDUiJx6uua8JDwj4X0yLamxA--WySFB3ZZxw7YQ
Vary: Origin
Vary: X-Origin
Content-Type: text/html; charset=UTF-8
Content-Length: 9
Date: Fri, 18 Aug 2017 12:48:24 GMT
Server: UploadServer
Alt-Svc: quic=":443"; ma=2592000; v="39,38,37,35"
Not Found
[res_header] => HTTP/1.1 200 Tunnel established
[res_body] => HTTP/1.1 404 Not Found
X-GUploader-UploadID: AEnB2Up-CJW9XP4E84DqWjZhI_8-YFgWR47UNNfqGkmM2S5EBf3H5aGOcuwHzLd-4faoKAxd_qgaO5GInDUiJx6uua8JDwj4X0yLamxA--WySFB3ZZxw7YQ
Vary: Origin
Vary: X-Origin
Content-Type: text/html; charset=UTF-8
Content-Length: 9
Date: Fri, 18 Aug 2017 12:48:24 GMT
Server: UploadServer
Alt-Svc: quic=":443"; ma=2592000; v="39,38,37,35"
Not Found
[errno] => 0
[error] =>
)
so, is the draft can not edited using a resumable upload?
How can I edit a draft with a large attachment?
when you update draft, it must used put.
like:
PUT https://www.googleapis.com/upload/gmail/v1/users/me/drafts/r6052444812129220058
Application Setup
Client - AngularJS (hosted at client.domain.com)
API + SignalR - Hosted at api.domain.com
SignalR setup class
public void Configuration(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie
});
app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
EnableJSONP = true
};
map.RunSignalR(hubConfiguration);
});
}
And I do following from Authentication service
AuthenticationManager.SignOut();
List<Claim> claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.Name, myuserid));
ClaimsIdentity id = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);
HttpContext.Current.GetOwinContext().Authentication.SignIn(new AuthenticationProperties() { IsPersistent = false }, id);
Authentication response looks like
HTTP/1.1 200 OK
Cache-Control: private
Pragma: no-cache
Content-Length: 556
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/7.5
Access-Control-Allow-Origin: *
Set-Cookie: ASP.NET_SessionId=pvasgf4q2klfbmk4oojqkxm5; path=/; HttpOnly
X-AspNet-Version: 4.0.30319
Set-Cookie: .AspNet.ApplicationCookie=1lBbz_FRNvxt1AhwkzZHFoiyhyZgsasNXStV3SbjQUHt0hqxTG--yXtjYNquB4zmQn-6M99pqHRPHaT4uf8g1JAnqg5WldD65IJ_FxYoEucf_WvV1fY4pwf774Cyo6fhI5nVk9Z6fdpjY422eo0GIibIMhaV9QvHNaiSsbFO0koT-CnhQuD5DED_418nP7m4FBbXdwIbFM_squ0bVYKXuB35jm57zVk9hUVWdlPmWxc; path=/; HttpOnly
X-Powered-By: ASP.NET
Date: Tue, 30 Dec 2014 00:20:29 GMT
When I the app makes request to signalr/negotiate, it receives 401 (unauthorized) because the cookie received in authentication response is not being sent with signalr request.
Is there anything I am missing?
UPDATE 1
All of above works fine when client and api are hosted in the same domain like this.
Client - www.domain.com/client
API - www.domain.com/api
UPDATE 2
Upon digging a little further, I realized that the issue is not related to signalr at all. I wrote a light client just to see if I can authenticate and follow that up with a simple get request. I hosted the client at api.domain.com/lightclient and made api requests to api.domain.com/api everything works. The following get request has the authentication cookie. However, when I moved the client to client.domain.com, browser removes the cookie.