Slim Framework 3 401 response can't set WWW-Authenticate header - rest

Have a REST application using Slim Framework v3. All works as expected, but I cannot seem to set headers for the response.
For example:
$app->any('/[{path:.*}]', function(Request $request, Response $response, $args = null ) use ( $objError, $objDBCon, $objUtil ) {
...
return $response->withAddedHeader( 'WWW-Authenticate', 'API-key realm="restricted"' )
->withJson($apiResults, $httpcode);
});
Works as expected in terms of getting data, getting the correct http status code, etc.
For example I get a the correct response JSON
{ "message": "You must be logged in to access this resource" }
and I get the expected status code:
Request Method:GET
Status Code:401 Unauthorized
and all the standard, correct headers, content-type, etc, etc.
But cannot seem to set any additional headers.
Reference documentaiton https://www.slimframework.com/docs/objects/response.html

My reputation is to low to add a comment:
According to the manual
withAddedHeader method appends the new value to the set of values that already exist for the same header name
Does your header already exists before appending?
I usually create a new header for each response, something like this:
return $response = $next($request, $response)
->withHeader('Access-Control-Allow-Origin', $this->allowedhosts)
->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
->withStatus(200);
hope this helps.

Related

Linkedin API request fails "Resource rest does not exist" when get sharesid

Good Morning,
I'm trying to get shareid of my test publication on Api Linkedin my request is:
https://api.linkedin.com/v2/rest/posts/shareUrn(urn:li:share:6947445733109194752)?X-Restli-Protocol-Version=2.0.0&LinkedIn-Version=202206
I also have my token but I don´t understand the reply:
{
"serviceErrorCode": 0,
"message": "Resource rest does not exist",
"status": 404
}
Any help is greatly appreciated
Thanks
you either go with 'V2' versioning or 'rest' versioning. The endpoints with headers should be (in python):
V2:
url = 'https://api.linkedin.com/v2/rest/posts/shareUrn/'
headers = {
'Authorization': f'Bearer {token}',
}
Rest:
url = 'https://api.linkedin.com/v2/rest/posts/shareUrn/'
headers = {
'Authorization': f'Bearer {token}',
'LinkedIn-Version': REST_VERSION,
}
where REST_VERSION is something like '202212'.
Optionally (not all LI endpoints accept it) you can add to the headers info about protocol:
"X-Restli-Protocol-Version": "2.0.0"
Remove "/rest" from the endpoint.
Include "X-Restli-Protocol-Version" and "LinkedIn-Version" in the header of the request.
Make sure all the query params in the request are in correct format.
Goodluck!

Paypal UNSUPPORTED_MEDIA_TYPE

I am trying to get an access token from paypal's authorization api.
When I make post request to the api I get UNSUPPORTED_MEDIA_TYPE i.e. 415 response.
Below is the snippet that I used.
const auth = await fetch(PAYPAL_OAUTH_API, {
method: 'post',
headers: {
'Content-Type': 'application/json',
'Authorization': `Basic ${ basicAuth }`
},
body: JSON.stringify({"grant_type": "client_credentials"})
});
I have fixed my issue by setting Content-Type to application/x-www-form-urlencoded.
My guess is paypal accepts only application/x-www-form-urlencoded for authorization api.
I ran into same issue, and the solution is following (using Postman):
Select POST
Add Token into Authorization, type is Bearer-Token
Select Content-Type: application/json in headers
Use RAW as body, and in TEXT dropdown, select JSON (application/JSON)
Copy body as raw object and change info accordingly.
Step 4 and 5 are what solved the error, you must send raw json object.

Error while generating access_token using Ebay 's REST API - Python requests

I'm trying to use the ebay REST-API for the first. I am simply trying to generate an access_token using the client credentials grant-request. I followed the instructions here https://developer.ebay.com/api-docs/static/oauth-client-credentials-grant.html
HTTP method: POST
URL (Sandbox): https://api.sandbox.ebay.com/identity/v1/oauth2/token
HTTP headers:
Content-Type = application/x-www-form-urlencoded
Authorization = Basic <B64-encoded_oauth_credentials>
Request body (wrapped for readability):
grant_type=client_credentials&
redirect_uri=<RuName-value>&
scope=https://api.ebay.com/oauth/api_scope
I'm getting this error: {'error': 'invalid_client', 'error_description': 'client authentication failed'} and my code looks like this:
path = 'https://api.sandbox.ebay.com/'
app_json = 'application/json'
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': base64.b64encode(b'Basic CLIENT_ID:CLIENT_SECRET')
}
payload = 'grant_type=client_credentials&redirect_uri=Searchez&scope=https://api.ebay.com/oauth/api_scope'
def get_oath_token():
url = 'https://api.sandbox.ebay.com/identity/v1/oauth2/token'
r = requests.post(url, headers=headers, data=payload)
print(r.json())
get_oath_token()
What do I have configured incorrectly? Thanks.
You're base64encoding "Basic " and shouldn't be.
The doc says just encode your Client ID + ":" + Client Secret, and leave the word "Basic" and the space that follows it alone.
In your code, i can see sandbox endpoint URI but in the request body scope, you have used production URL, instead of sandbox

How get access_token from body for use in another method

Good afternoon. Slightly confused in the Gatling documentation, I can not find a solution. I want to get a token to use in another method as a header. Here is an example of the first method where I get a token:
exec(
http("HTTP Request auth")
.post("http://blabla:9001/connect/token")
.header("Content-Type","application/x-www-form-urlencoded")
.formParam("grant_type","password")
.formParam("username", "${login}")
.formParam("password", "${password}")
.formParam("client_id","ro.client")
.formParam("client_secret","secret")
.check(status is 200)
.check(header("access_token").saveAs("access_token"))
.check(header("token_type").saveAs("token_type"))
)
Here's the second method, where I want to pass the token:
.exec(
http("HTTP Request createCompany")
.post("/Companies/CreateCompany")
.header("Authorization","${token_type} + ${access_token}")
.check(status is 200)
)
As a result, writes that a token was not found:
Request:
HTTP Request auth: KO header(access_token).find(0).exists, found nothing
But then he writes:
body={"access_token":"7e8c1d997dd92f16a87fa7ffb8a88ab14eb05a8883d78fe8652d072f24b5ca4a","expires_in":31536000,"token_type":"Bearer"}
I guess I find it wrong here:
.check(header("access_token").saveAs("access_token"))
.check(header("token_type").saveAs("token_type"))
The body of the first request is a Json payload, you need to use jsonPath, which is like XPath for Json:
.check(jsonPath("$.access_token").saveAs("access_token"))
.check(jsonPath("$.token_type").saveAs("token_type"))
Also, the header of the second request will print as:
.header("Authorization", "${token_type} + ${access_token}")
=> Authorization: Bearer + 7e8c1d997dd92f16a87fa7ffb8a88ab14eb05a8883d78fe8652d072f24b5ca4a
Unless you really want the extra +, the right header construction might be:
.header("Authorization", "${token_type} ${access_token}")
One way is to do like this ->
exec { session => var access_token ='' ;
your exec code
session.setAll( "token_type" -> access_token );
}
Then token_type is available to use.

Using cors across two independently running local apps

I have two applications running indepepently, one taking care of my backend (written in Scala Play) then other one being my frontend (Angular with a static Node server).
I try to request data on my frontend through a form from my Scala Play app.
this.insertionOrder = function(){
$http({
method: 'POST',
url: '//localhost:9000/insertsupplier',
header: {
'Content-type': 'application/json',
'Access-Control-Allow-Origin' : '*',
'Access-Control-Allow-Methods' : 'POST, GET, OPTIONS'
},
data:{
'supplier_id': 1,
'suppliername': 'xxx',
'supplier_address': 'xxx xxx xxx xxx',
'contact': 'xxx#xxx.com',
'datecreated': '2017-10-15T09:45:00.000UTC+00:00'
}
}).then(function(response){
console.log(response);
return response.data
}, function(err){
console.log(err)
});
};
and my play app looks like this:
Controller:
def insertsupplier = Action(parse.json) { implicit request =>
val json = request.body
val sup: Supplier = json.as[Supplier]
sup.insertSql(con)
Ok("test")
}
my build.sbt contains filters:
libraryDependencies ++= Seq(
cache ,
ws,
jdbc,
filters
)
and the MyFilters.scala
class MyFilters (implicit inj:Injector) extends HttpFilters with Injectable {
implicit val as = inject[ActorSystem]
implicit val mat = ActorMaterializer()
val gzip = new GzipFilter()
val csrf = inject[CSRFFilter]
val cors = inject[CORSFilter]
//println(s"csrf: ${csrf.tokenProvider}")
//println(s"csrf: ${csrf.tokenProvider.generateToken}")
def filters = Seq(gzip,cors,csrf)
}
and finally my application.conf
play.filters.cors {
pathPrefixes = ["*"]
allowedOrigins = ["http://localhost:3000","https://localhost:3000","http://localhost:3000/*","https://localhost:3000/*"]
allowedHttpMethods = ["GET", "POST", "OPTIONS"]
allowedHttpHeaders = ["Accept"]
# preflightMaxAge = 1 hour
}
play.filters.csrf {
cookie.name = "XSRF-TOKEN"
header.name = "X-XSRF-TOKEN"
}
play.http.filters = "filters.MyFilters"
I keep getting the error "XMLHttpRequest cannot load http://localhost:9000/insertsupplier. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 500."
I feel that first my CORS setup is wrong anyway --> What needs to be changed? I am new to this.
And am I even able to use cors in order to access data from localhost?
It may be that there’s nothing wrong at all with your CORS setup, because the “The response had HTTP status code 500” part of the error message indicates that the actual immediate problem is that an OPTIONS request to your server caused some unexpected failure on the server side.
From just the code snippets in the question, it’s not possible to tell what might be causing that 500 failure in the server side. It may be completely unrelated to your CORS config.
But regardless, you should drop the parts of your frontend code that are adding the header 'Access-Control-Allow-Origin' : '*', and 'Access-Control-Allow-Methods'. Those headers are response headers that must be sent from the server side, not from frontend code.
But the 'Content-type': 'application/json' part of your frontend code is valid, and assuming it’s actually necessary in order to get the expected response from the server, there’s no way you can make your request without triggering browsers to do a CORS preflight OPTIONS request.
But if the CORS preflight OPTIONS request fails, the browser never gets around to trying the POST request your code is actually attempting to send. And if your backend responds to that OPTIONS request with a 500 response, then the preflight fails. It must instead respond with a 200 or 204.