Getting a token and how to build the .exec

1,249 views
Skip to first unread message

Magnus Jensen

unread,
Jan 8, 2015, 4:45:48 AM1/8/15
to gat...@googlegroups.com
I want to do a call to a token-service like this in Gatling:

---- REQUEST:  ----

POST http://idpt.company.com/ids/connect/token HTTP/1.1

Authorization: Basic bW9iaWxlX2NsaWVudDptb2JpbGVfc2VjcmV0

host: idpt.company.com

content-type: application/x-www-form-urlencoded; charset=utf-8

content-length: 103

Connection: keep-alive

username=theusername&password=thepassword&scope=small&proxy=http%3A%2F%2Flocalhost%3A8888&grant_type=password


This (POST) request should respons with a token.

My question is how to I "translate" the request above into an .exec in Gatling?

The Authorization: Basic i.e. how can I state that in the .exec?
It is static and can be the same for every request I make.


Cheers

Magnus Jensen

unread,
Jan 8, 2015, 5:33:02 AM1/8/15
to gat...@googlegroups.com
I solved this like this:

.exec(
 
http("getToken")
   
.post("https://id.company.com/ids/connect/token")
   
.headers(Map("Content-Type" -> "application/x-www-form-urlencoded; charset=utf-8" , "Authorization" -> "Basic bW9iaWxlX2xxxxxxmV0"))
   
.body(StringBody("username=theusername&password=thepassword&scope=small&proxy=http%3X%2F%2Flocalhost%3A8888&grant_type=password"))
   
.asFormUrlEncoded
)



On Thursday, January 8, 2015 10:45:48 AM UTC+1, Magnus Jensen wrote:
I want to do a call to a token-service like this in Gatling:

---- REQUEST:  ----

POST http://idpt.company.com/ids/connect/token HTTP/1.1

Authorization: Basic bW9iaWxlX2NsaWVudDptb2JpbGVfc2VjcmV0

host: idpt.company.com

content-type: application/x-www-form-urlencoded; charset=utf-8

content-length: 103

Connection: keep-alive

username=theusername&password=thepassword&scope=small&proxy=http%3X%2F%2Flocalhost%3A8888&grant_type=password


This (POST) request should respons with a token.

Stéphane Landelle

unread,
Jan 8, 2015, 10:11:58 AM1/8/15
to gat...@googlegroups.com
Actually, you shouldn't craft the Authorization header yourself (nor hardcode it).

--
You received this message because you are subscribed to the Google Groups "Gatling User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gatling+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Magnus Jensen

unread,
Jan 8, 2015, 10:45:45 AM1/8/15
to gat...@googlegroups.com
Ok. 
I know how my Authorization header is made.
It is just a base64encode of two values, lets say:
c29tZV9jbGllbnQ6c29tZV9zZWNyZXQ=
which decodes to:
some_client:some_secret

Is there a way to decode 'some_client' and 'some_secret' on the fly?

Should I do it in the header-mapping

.headers(Map("Content-Type" -> "application/x-www-form-urlencoded; charset=utf-8" , "Authorization" -> "Basic c29tZV9jbGllbnQ6c29tZV9zZWNyZXQ="))

Or as a separate function?




Steven Zaluk

unread,
Jan 8, 2015, 3:09:05 PM1/8/15
to gat...@googlegroups.com
I had to do something similar where I had to dynamically create an Authorization and Content-MD5 header for each request that is computed based on the payload of the request.  I created a SignatureCalculator and that works perfectly.

--Steve

Magnus Jensen

unread,
Jan 8, 2015, 3:32:03 PM1/8/15
to gat...@googlegroups.com
Would it be possible to share the "calculator"?

Stéphane Landelle

unread,
Jan 8, 2015, 3:39:15 PM1/8/15
to gat...@googlegroups.com
Here, we're talking about plain old Basic authentication.
As it's a very very very very standard mechanism, of course Gatling supports it out of the box.
I already sent a pointer to the documentation in a previous mail in this very same thread!

Magnus Jensen

unread,
Jan 9, 2015, 4:56:07 PM1/9/15
to gat...@googlegroups.com
Ok,

So then I have:

package com.site

import io.gatling.core.Predef._
import io.gatling.core.scenario.Simulation
import io.gatling.http.Predef._

class idpSimulation extends Simulation{


 
val httpConf = http
    .baseURL("https://id.site.com/ids")
   
.acceptEncodingHeader("gzip,deflate")
   
.headers(Map("Content-Type" -> "application/x-www-form-urlencoded; charset=utf-8"))
   
.authorizationHeader("Basic bW9PaWxlX2NsaWZudDptbpJpxVfc2VjcmV0")
   
.disableUrlEscaping

 
val scn = scenario("Scenario")

   
.feed(csv("data/testdata.csv").random)

   
.exec(
     
http("getToken")
       
.post("/connect/token").basicAuth("${MemberId}", "password")
       
//.body(StringBody("username=${MemberId}&password=password&scope=legacy&proxy=http%3A%2F%2Flocalhost%3A8888&grant_type=password"))
        .asFormUrlEncoded
       
.check(jsonPath("$.access_token").exists.saveAs("token")))

  setUp
(scn.inject(atOnceUsers(1)).protocols(httpConf))
}

But what do I do with the remaing part of the string body (commented out above). How do I define the part:

...scope=legacy&proxy=http%3A%2F%2Flocalhost%3A8888&grant_type=password

in my simulation? still as a string body without the username and password?

Magnus Jensen

unread,
Jan 9, 2015, 5:03:59 PM1/9/15
to gat...@googlegroups.com
If I remove the username and password from the string body and put it into a basicauth and run the simulation my logging says:

=========================
HTTP request:
headers=
Accept-Encoding: gzip,deflate
Content-Type: application/x-www-form-urlencoded
Authorization: Basic bW9iaWxlXsNsaWVddDptb2JpbwVfc2VjcmV0
Content-Length: 68
Connection: keep-alive
Authorization: Basic ODMxNTU3MjMdMzpwYdNzMTIz
Accept: */*
compositeByteData=scope=legacy&proxy=http%3Z%2F%2Flocalhost%3A8988&grant_type=password
realm=Realm{principal='removedbyme', password='pass123', scheme=BASIC, realmName='', nonce='', algorithm='MD5', response='', qop='auth', nc='00000001', cnonce='', uri='null', methodName='GET', useAbsoluteURI='true', omitQuery='false'}
=========================
HTTP response:
status=
400 Bad Request
headers= 
Content-Type: [text/html; charset=us-ascii]
Server: [Microsoft-HTTPAPI/2.0]
Date: [Fri, 09 Jan 2015 21:59:34 GMT]
nnCoection: [close]
Content-Length: [339]

body=
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>Bad Request</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
<BODY><h2>Bad Request - Invalid Header</h2>
<hr><p>HTTP Error 400. The request has an invalid header name.</p>
</BODY></HTML>

<<<<<<<<<<<<<<<<<<<<<<<<<




Abhinav Gogna

unread,
Jan 9, 2015, 5:43:55 PM1/9/15
to gat...@googlegroups.com
If you look at the logs, it shows that you have two authorization headers in your http request. You only need to send one.

one way would be
val httpConf = http
    .baseURL("https://id.site.com/ids")
   
.acceptEncodingHeader("gzip,deflate")
   
.headers(Map("Content-Type" -> "application/x-www-form-urlencoded; charset=utf-8"))

   
//.authorizationHeader("Basic bW9PaWxlX2NsaWZudDptbpJpxVfc2VjcmV0") //--- remove this authorization headers
   
.basicAuth(username: "<yourUserName>",password: "<yourPassword>")
   
.disableUrlEscaping



.exec(
     
http("getToken")
       
.post("/connect/token"
)
       
//.
basicAuth("${MemberId}", "password") -- remove this from here
       
//.body(StringBody("username=${MemberId}&password=password&scope=legacy&proxy=http%3A%2F%2Flocalhost%3A8888&grant_type=password"))
        .asFormUrlEncoded
       
.check(jsonPath("$.access_token").exists.saveAs("token")))


If you set up your authorization at protocol level, then you won't have to add it every get/post exec().

Magnus Jensen

unread,
Jan 9, 2015, 6:16:57 PM1/9/15
to gat...@googlegroups.com
Yes but what do I do with the remaining part of the:

.body(StringBody("username=${MemberId}&password=password&scope=legacy&proxy=http%3A%2F%2Flocalhost%3A8888&grant_type=password")

 as in:

scope=legacy&proxy=http%3A%2F%2Flocalhost%3A8888&grant_type=password"

I cannot just say:

.body(StringBody("scope=legacy&proxy=http%3A%2F%2Flocalhost%3A8888&grant_type=password"))

That is what causing the error reported earlier.

Abhinav Gogna

unread,
Jan 9, 2015, 7:15:54 PM1/9/15
to gat...@googlegroups.com
I am not sure what exactly that is. But you can try following options

1) Leave that as is. Since this is not part of the header, it may not give 400 error
2) It could be a formParam - try using .formParam http://gatling.io/docs/2.1.2/http/http_request.html#query-parameters
3) If it is a proxy then declare proxy setting globally - http://gatling.io/docs/2.1.2/http/http_protocol.html#proxy-parameters

Debug it.

Meena Dappili

unread,
Jul 23, 2019, 2:56:50 AM7/23/19
to Gatling User Group

I am getting the same token for login response like [ Authorization : Bearer fsdjflkajsfjlasjfjdsafjajfkafkdsajkfalj--> token value] 
i could able to capture the token.

this token is same for all further requests, i am unable to pass this header value to all the further requests.
the requests are like api call related http requests.

Can you help me with how to add this header to further request.

i tried with

val sessionHeaders = Map("Authorization" -> "Bearer ${token}",
                           "Content-Type" -> "application/json")

i passed the same header value like below.
.get("/smee/common/categoryList")   -----> this http request will trigger api call.
.headers(sessionHeaders)

please any one help me on this. Thanks in advance.

G Madhana Mohana Reddy

unread,
Jul 27, 2019, 1:57:05 AM7/27/19
to Gatling User Group

G Madhana Mohana Reddy

unread,
Jul 27, 2019, 1:57:23 AM7/27/19
to Gatling User Group
Hi Meena,

Please follow the below sample template/code for header implementation.

object xxxxx {
val xxxxxx =exec(http("Main_Request")
.post("/")
.headers(headers_2)
.header("Authorization","Bearer ${Beaererid}")
.body(StringBody("""<<<<request body>>>>"""))
.check(status.in(200))
)
}


or 

val headers_2 = Map(
"Accept" -> "*/*",
"Accept-Encoding" -> "gzip, deflate, br",
"Connection" -> "keep-alive",
"content-type" -> "application/json",
"region" -> "IN",
"x-status" -> "Auth",
"X-APIKEY" -> "<your api key"
)

On Thursday, January 8, 2015 at 3:15:48 PM UTC+5:30, Magnus Jensen wrote:

Meena Dappili

unread,
Jul 29, 2019, 4:54:42 AM7/29/19
to Gatling User Group
Why this is marked as abuse? It has been marked as abuse.
Report not abuse
Hi Madan,

import scala.concurrent.duration._

import io.gatling.core.Predef._
import io.gatling.http.Predef._
import io.gatling.jdbc.Predef._

class ChangeRecordedSimulation extends Simulation {

val sessionHeaders = Map("Authorization" -> "Bearer ${authToken1}",
                           "Content-Type" -> "application/json")

val httpProtocol = http
.inferHtmlResources()
.acceptHeader("application/json, text/plain, */*")
.userAgentHeader("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36")

val headers_0 = Map(
"Accept" -> "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
"Upgrade-Insecure-Requests" -> "1")

val headers_17 = Map(
"Content-Type" -> "application/json;charset=UTF-8",
"Origin" -> "https://xxx.xxx.com",
"X-Requested-With" -> "XMLHttpRequest")

val headers_18 = Map(
"X-Requested-With" -> "XMLHttpRequest",
"authorization" -> "Bearer ${authToken1}",
"content-type" -> "application/json")

val headers_20 = Map(
"X-Requested-With" -> "XMLHttpRequest",
"authorization" -> "Bearer ${authToken1}")
 

val headers_21 = Map(
"Content-Type" -> "application/json;charset=UTF-8",
"Origin" -> "https://xxxx.xxxx.com",
"X-Requested-With" -> "XMLHttpRequest",
"authorization" -> "Bearer ${authToken1}")

val headers_37 = Map(
"Origin" -> "https://xxxx.xxxx.com",
"X-Requested-With" -> "XMLHttpRequest",
"authorization" -> "Bearer ${authToken1}",
"content-type" -> "application/json")


val scn = scenario("ChangeRecordedSimulation")
.exec(http("request_0")
.get("/xxx/ui/")
.headers(headers_0))
.pause(1)
.exec(http("request_1")
.get(uri3 + "/ionicons/2.0.1/css/ionicons.min.css")
.headers(headers_0)
.resources(http("request_2")
.get(uri3 + "/font-awesome/4.5.0/css/font-awesome.min.css")
.headers(headers_0),
            http("request_3")
.get(uri2 + "?family=Roboto+Condensed")
.headers(headers_0),
            http("request_4")
.get("/xxx/ui/static/css/_all-skins.min.css")
.headers(headers_0),
            http("request_5")
.get("/xxxx/ui/static/css/AdminLTE.min.css")
.headers(headers_0),
            http("request_6")
.get("/xxxx/ui/static/css/bootstrap.min.css")
.headers(headers_0),
            http("request_7")
.get("/xxxx/ui/static/css/pace.min.css")
.headers(headers_0),
            http("request_8")
.get("/xxxx/ui/static/js/jquery.slimscroll.min.js")
.headers(headers_0),
            http("request_9")
.get("/xxxx/ui/static/js/manifest.31b3b1b0528463613ec1.js")
.headers(headers_0),
            http("request_10")
.get(uri2 + "?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic")
.headers(headers_0),
            http("request_11")
.get("/xxxx/ui/static/js/jquery-2.2.3.min.js")
.headers(headers_0),
            http("request_12")
.get("/xxxx/ui/static/js/bootstrap.min.js")
.headers(headers_0),
            http("request_13")
.get("/xxxx/ui/static/css/app.176431924930ce0b6fc1f73d1f4795c0.css")
.headers(headers_0),
            http("request_14")
.get("/xxxx/ui/static/js/pace.min.js")
.headers(headers_0),
            http("request_15")
.get("/xxxx/ui/static/js/app.99a07150331050539321.js")
.headers(headers_0),
            http("request_16")
.get("/xxxx/ui/static/js/vendor.c94789110b7f7b9fc3be.js")
.headers(headers_0),
            http("LogIn")
.post("/xxxx/usermanagement/userCurrent")
.check(jsonPath("$..token").exists.saveAs("authToken1"))
.headers(headers_17)
.body(RawFileBody("ChangeRecordedSimulation_0017_request.txt")),
            http("request_18")
.get("/xxxx/common/clientUserInactiveTimeout")
.headers(headers_18),
            http("request_19")
.get("/xxxx/common/help-menu2?userFunctionId=10")
.headers(sessionHeaders),
//.headers(headers_18),
            http("request_20")
.get("/xxxx/notification/dashboardStatistics?userFunctionGroupId=10&categoryCodeList=")
.headers(sessionHeaders),
//.headers(headers_20),
            http("request_21")
.post("/xxxx/changemanagement/api/checkUserHierarchyMapping")
.headers(sessionHeaders)
//.headers(headers_21)
.body(RawFileBody("ChangeRecordedSimulation_0021_request.txt")),
            http("request_22")
.get("/xxxx/common/dataTablePreferences?dataTableCode=Step2-From-Datatable1&userSid=17")
.headers(sessionHeaders),
//.headers(headers_20),
            http("request_23")
.get("/xxxx/common/dataTablePreferences?dataTableCode=Step2-To-Datatable1&userSid=17")
.headers(headers_20),
            http("request_24")
.get("/xxxx/common/dataTablePreferences?dataTableCode=Step2-From-Datatable5&userSid=17")
.headers(headers_20),
            http("request_25")
.get("/xxxx/common/dataTablePreferences?dataTableCode=Step2-To-Datatable5&userSid=17")
.headers(headers_20),
            http("request_26")
.get("/xxxx/common/dataTablePreferences?dataTableCode=Step3-Datatable5&userSid=17")
.headers(headers_20),
            http("request_27")
.get("/xxxx/common/dataTablePreferences?dataTableCode=Step3-Datatable1&userSid=17")
.headers(headers_20),
            http("request_28")
.get("/xxxx/common/dataTablePreferences?dataTableCode=Step4-Datatable1&userSid=17")
.headers(headers_20),
            http("request_29")
.get("/xxxx/common/dataTablePreferences?dataTableCode=Step3-Datatable4&userSid=17")
.headers(headers_20),
            http("request_30")
.get("/xxxx/common/dataTablePreferences?dataTableCode=Step2-From-Datatable2&userSid=17")
.headers(headers_20),
            http("request_31")
.get("/xxxx/common/dataTablePreferences?dataTableCode=Step2-To-Datatable2&userSid=17")
.headers(headers_20),
            http("request_32")
.get("/xxxx/common/dataTablePreferences?dataTableCode=Step3-Datatable2&userSid=17")
.headers(headers_20),
            http("request_33")
.get("/xxxx/common/dataTablePreferences?dataTableCode=Datatable-PCL-CreateByExcelNewChase&userSid=17")
.headers(headers_20),
            http("request_34")
.get("/xxxx/common/searchPanelUserPreferences?userSid=17&searchPanelCode=chaseSearchPanel")
.headers(headers_18),
            http("request_35")
.get("/xxxx/common/searchPanelUserPreferences?userSid=17&searchPanelCode=chaseTagSearchPanel")
.headers(headers_18),
            http("Search")
.post("/xxxx/changemanagement/api/newChaseCreateSearch")
.headers(headers_21)
.body(RawFileBody("ChangeRecordedSimulation_0036_request.txt")),
            http("request_37")
.put("/xxxx/common/searchPanelUserPreferences")
.headers(headers_37)
.body(RawFileBody("ChangeRecordedSimulation_0037_request.txt")),
            http("request_38")
.post("/xxxx/changemanagement/api/newChaseCreateSearchStep3")
.headers(headers_21)
.body(RawFileBody("ChangeRecordedSimulation_0038_request.txt")),
            http("request_39")
.post("/xxxx/changemanagement/api/newChaseRequestSave")
.headers(headers_21)
.body(RawFileBody("ChangeRecordedSimulation_0039_request.txt")))
// 
)
.exec { session =>
   println()
    println("authToken1")
println()
println( session("authToken1").as[String] )
  session
}

setUp(scn.inject(atOnceUsers(1))).protocols(httpProtocol)
}

Note:
Under UserCurrent request using JasonPath i could able to capture the token, which is generating as a response for login page.
when i am replacing the token in headers : authorization : bearer {authtoken1} 

getting an error like :
request_18: Failed to build request: No attribute named 'authToken1' is defined.

what i want:
i want to pass the token to all the further request by replacing in all the authorization header value at the top, but it is not working for me.


please help me on this, i am really blocked.

Thanks in advance.
Reply all
Reply to author
Forward
0 new messages