How get access_token from body for use in another method - scala

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.

Related

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

Read full request URL in Play Web Framework

I am trying to read full URL which comes with #params. How can i read in Play controller? I am able to read query parameters but not route directive
ex : https://x.app.com/callback#x=1
Action.async{ implicit request =>
val fullUrl = ??? //Read full url of request
}
I tried request.uri and request.path. both are not helpful.
response of request.uri => /callback
response of request.path => /callback
There are no #params in the response.
you can use:
request.path
or
request.uri
You cant pass fragment (# part) to server, it is browser only. Use query parameter instead

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

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.

loopback access_token not found

followed by the access documentation
both are not working by using
Authorization Header
Query Parameter
Using the latest version of loopback 2.1.X.
I turned off the email verification and successfully got the AccessToken object from the initial login. The header and the query request are not working now.
ACCESS_TOKEN=6Nb2ti5QEXIoDBS5FQGWIz4poRFiBCMMYJbYXSGHWuulOuy0GTEuGx2VCEVvbpBK
Authorization Header
curl -X GET -H "Authorization: $ACCESS_TOKEN" \
http://localhost:3000/api/widgets
Query Parameter
curl -X GET http://localhost:3000/api/widgets?access_token=$ACCESS_TOKEN
In header pass key as authorization not ACCESS_TOKEN
In query params pass key as accessToken not access_token
Here is what works for me in Angular 2 :
initRequestOptions(accessToken:any) {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Access-Control-Allow-Origin', '*');
headers.append('Authorization', accessToken);
return new RequestOptions({headers: headers});
}
makeRequest(accessToken:any){
let options = this.initRequestOptions(accessToken);
this.http.get('http://' + apiUrl + '/api/MyModel, options)
.subscribe(
//...
)
}
So basically you need to create a headers object , add an 'Authorization' item whoes value is the access token , and use the headers object to create a RequestOptions object to be inserted in the request.
Also loopback explorer passes the access token as a url encoded parameter so this should work too :
http://localhost:3000/api/MyModel?access_token=X3Ovz4G1PfmPiNGgU5YgORPwPGLaVt9r8kU7f4tu1bDMyA4zbqiUEgeDAC3qkZLR

Jhipster + REST client + authentication

I need to understand how to authenticate a REST client (could be Paw, could be an android app, an iOs app using AFNetworking with jHipster and I think, more in general, with spring-boot of which I am no expert).
While I am able to obtain a token when logged in a browser, and subsequently use this token in the following requests, I do not understand how I can authenticate in the first place using RESTful best practices.
For example, in Paw.app, I can pass a Basic authentication, or Oauth2, but I don't understand how to get the session token simply authenticating as I do on a web browser.
Similarly, in AFNetworking I am able to pass basic authentication, e.g.
NSString*auth=[NSString stringWithFormat:#"%#:%#", #"admin", #"admin"];
NSString *authValue = [NSString stringWithFormat:#"Basic %#", [auth base64EncodedString]];
[manager.requestSerializer setValue:authValue forHTTPHeaderField:#"Authorization"];
But I struggle to understand how to authenticate with the session security which is bundled in jHipster/spring boot.
First of all, do not use HTTP session authentication for mobile apps.
On the other hand, Oauth2 or JWT works fine with mobile apps. The basic idea behind them is to get a token from Jhipster to mobile the token has an expiry time. In that time you can use the token to access any REST API of Jhipster to access data.
Below I am showing the code snippet of how I was using the Jhipster rest API in my angularjs based ionic app. I hope it gives the idea of what you need to do.
uncomment cors in application.yml inside jhipster
cors: #By default CORS are not enabled. Uncomment to enable.
allowed-origins: "*"
allowed-methods: GET, PUT, POST, DELETE, OPTIONS
allowed-headers: "*"
exposed-headers:
allow-credentials: true
max-age: 1800
To access REST API with Oauth2 authentication in ionic you must first get the token in the ionic app by
$http({
method: "post",
url: "http://192.168.0.4:8085/[Your app name]/oauth/token",
data: "username=admin&password=admin&grant_type=password&scope=read write&client_secret=my-secret-token-to-change-in-production&client_id=auth2Sconnectapp",
withCredentials: true,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json',
'Authorization': 'Basic ' + 'YXV0aDJTY29ubmVjdGFwcDpteS1zZWNyZXQtdG9rZW4tdG8tY2hhbmdlLWluLXByb2R1Y3Rpb24='
}
})
.success(function(data) {
alert("success: " + data);
})
.error(function(data, status) {
alert("ERROR: " + data);
});
Here "YXV0aDJTY29ubmVjdGFwcDpteS1zZWNyZXQtdG9rZW4tdG8tY2hhbmdlLWluLXByb2R1Y3Rpb24=" is equal to (clientId + ":" + clientSecret)--all base64-encoded
The above $http if successful will give you this JSON which contains token and it's expiry time
{
"access_token": "2ce14f67-e91b-411e-89fa-8169e11a1c04",
"token_type": "bearer",
"refresh_token": "37baee3c-f4fe-4340-8997-8d7849821d00",
"expires_in": 525,
"scope": "read write"
}
Take notice of "access_token" and "token_type" if you want to access any API this is what you have to use. We send the token with API to access data until the token expires then we either refresh it or access for a new one.
For example
$http({
method: "get",
url: "http://192.168.0.4:8085/auth-2-sconnect/api/countries",
withCredentials: true,
headers: {
'Authorization':' [token_type] + [space] + [access_token] '
}
})
.success(function(data) {
alert("success: " + data);
})
.error(function(data, status) {
alert("ERROR: " + data);
});
Here a summarisation of how I implemented the solution. It’s real swift code, but please take it as pseudocode, as it might be incorrect.
make a call to whatever method you need to call, passing in such method a callback (block, or equivalent) for the success and one for the failure
func action(
URLString:String,
method:Method,
encoding:Encoding = .JSON,
parameters:[String : AnyObject]?,
success:(statusCode:Int, responseObject:AnyObject)->Void,
failure:(statusCode:Int, error:NSError)->Void
)
Inside the method es. /events you handle a particular case of failure, which is when the status code is 401.
if(r!.statusCode==ResponseCodes.HTTP_UNAUTHORIZED.rawValue){
loginAndAction(URLString, method: method, encoding: encoding, parameters: parameters, success: success, failure: failure)
}else{
failure(statusCode: response.response!.statusCode, error:response.result.error!)
}
In this particular case, instead of returning back the result and calling the failure callback, you call a login() method which, after the necessary parameters, accept the original success() callback
func loginAndAction(
URLString:String,
method:Method,
encoding: Encoding,
parameters:[String:AnyObject]?,
success:(statusCode:Int, responseObject:AnyObject)->Void,
failure:(statusCode:Int, error:NSError)->Void
)->Void
if the authentication succeeds
var d:[String:AnyObject] = response.result.value as! [String:AnyObject]
self.authToken = d["access_token"] as! String
action(URLString, method: method,encoding:encoding, parameters: parameters, success: success, failure: failure)
at this point the method action could use a proper working token.
This should happen only once a day (based on the token expiration), and it is a mechanism appliable to the oauth2 refresh_token call.