Automatic testing your app with Login preprod

Last updated: March 23, 2023

Introduction

To automate your test in preproduction, you may need a member access token, representing a user's credentials.

Login offer a way to get a token without using the frontend, bypassing the google recaptcha we are using to protect us against bots.

In short :

  • Get a BypassCaptcha token (1 step)
  • Follow the Login OAuth flow (5 steps)
  • Get a token

Important

This feature is not allowed in Production.

To know

  • Login is protected by a WAF (cloudflare), if you ask to many requests in a short time you will trigger the WAF and it will block you, likely with some HTTP 429 errors.
  • Login does not manage cloudflare, you may have to ask the infra team of Member BU to whitelist the IP of your machine.
  • Login rely on an identity provider to verify the user credentials. This identity provider has its own protection against botting. Login may return an error triggered by the identity provider, likely a HTTP 429. When the identity provider block an account (likely for 1h), change the email/password you are using if you don't want to wait.

Prerequisites

  • The client-id of your application : CLIENT_ID in the rest of the document
  • A redirect_uri of the client
    • In its plain form and in its encoded form
    • In the rest of the document, the redirect_uri used is https://ancient-citadel-79703.herokuapp.com/oauth-client/auth/callback
    • The encoded form is https%3A%2F%2Fancient-citadel-79703.herokuapp.com%2Foauth-client%2Fauth%2Fcallback
  • The client-id and client-secret of a dedicated BypassCaptcha client. You can ask us such a client here
    • scope: bypass_captcha
    • resource id: https://api-eu.preprod.decathlon.net/connect
  • The API key from APIm to reach Login in preproduction : API_KEY in the rest of the document
  • The valid email and password of a user : USER_EMAIL and USER_PASSWORD in the rest of the document

Getting a Bypass Catptcha token

To get a Bypass Captcha token, simply do a client-credentials with the Bypass Captcha client credentials.

Note the access_token you received, we will refer to it as BYPASS_CAPTCHA_TOKEN in the rest of the document

Login OAuth flow

This part contains 5 steps


Some parameter are hard coded, as for a testing token they do not matter much.
  • code_challenge
  • code_verifier
  • code_challenge_method



Step 1 : Authorize

curl --location 'https://api-global.preprod.decathlon.net/connect/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=https%3A%2F%2Fancient-citadel-79703.herokuapp.com%2Foauth-client%2Fauth%2Fcallback&state=MR25aFnIWnSkWEgQ6OZu1f0dRCSpd9WF&code_challenge=mGH3Gcvmq_lmc5fB3DBvN_aKwh3scIlQezkB7ed5qTE&code_challenge_method=S256'
                                                    
                                                
The response of this call should return a HTTP 302.

This step start a session with the client.

Step 2 : Lookup

curl --location 'https://api-global.preprod.decathlon.net/connect/lookup?client_id=CLIENT_ID' \
--header 'Content-Type: application/json' \
--header 'X-API-Key: API_KEY' \
--header 'X-CAPTCHA-BYPASS: BYPASS_CAPTCHA_TOKEN' \
--data-raw '{"email":"USER_EMAIL"}'
                                                    
                                                
The response of this call should return a HTTP 200 with a json.

This step start a session with the user in Login.



Step 3 : Login

curl --location 'https://api-global.preprod.decathlon.net/connect/login?client_id=CLIENT_ID' \
--header 'X-API-Key: API_KEY' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'X-CAPTCHA-BYPASS: BYPASS_CAPTCHA_TOKEN' \
--data-urlencode 'login_type=email' \
--data-urlencode 'password=USER_PASSWORD'
                                                    
                                                
The response of this call should return a HTTP 200 with a HTML page.
The following step is the link you can find the the action property of the returned form of the HTML.



Step 4 : Authorize (bis)

curl --location --request POST 'https://api-global.preprod.decathlon.net/connect/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=https%3A%2F%2Fancient-citadel-79703.herokuapp.com%2Foauth-client%2Fauth%2Fcallback&state=MR25aFnIWnSkWEgQ6OZu1f0dRCSpd9WF&code_challenge=mGH3Gcvmq_lmc5fB3DBvN_aKwh3scIlQezkB7ed5qTE&code_challenge_method=S256' \
--header 'X-CAPTCHA-BYPASS: BYPASS_CAPTCHA_TOKEN'
                                                    
                                                
The response of this call should return a HTTP 303.

In this step, you have to parse the response from Login, to get the code to exchange : CODE in the following step
The code is located in the header Location of the response.
Example of a response header Location : https://ancient-citadel-79703.herokuapp.com/oauth-client/auth/callback?code=EUKAxD96&state=62GRK7R3RtuIczCNfNxmmNk9YEpiqlBi Here the code is EUKAxD96



Step 5 : Exchange code

curl --location 'https://api-global.preprod.decathlon.net/connect/oauth/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'code=CODE' \
--data-urlencode 'redirect_uri=https://ancient-citadel-79703.herokuapp.com/oauth-client/auth/callback' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'state=MR25aFnIWnSkWEgQ6OZu1f0dRCSpd9WF' \
--data-urlencode 'code_verifier=Z7pEAEh0D4xGTwRPtxwKJy-y5mCY4POVSRnW6MUbdc4' \
--data-urlencode 'client_id=CLIENT_ID'
                                                
                                            
The response of this call return an access_token and a refresh_token.

For example :

{
    "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0MTFlYzA2NS03NDI2LTRjYjQtYWNjNC1jZGUwNzhlNTU4MjkiLCJhdXRoX3RpbWUiOjE2Nzk1NzE0MjIsInNjb3BlIjpbInByb2ZpbGU6d3JpdGUiLCJlbWFpbDp3cml0ZSIsImdlbmRlciIsInBob25lIiwib3BlbmlkIiwicHJvZmlsZSIsImVtYWlsIiwiY29udGFjdHMiLCJjb250YWN0czp3cml0ZSJdLCJpc3MiOiJodHRwczovL2FwaS1ldS5wcmVwcm9kLmRlY2F0aGxvbi5uZXQvY29ubmVjdCIsImRhdGFfY2VudGVyIjoiRVUiLCJwZXJzb25pZCI6Ijk5MDE2MTI2ODE5IiwibG9jYXRpb24iOiJGUiIsImV4cCI6MTY3OTU3MjMyOSwiaWF0IjoxNjc5NTcxNDI5LCJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwianRpIjoiQlo2M013VzVfc0xOLUh6MDZJQXBySWRMeFNvIiwiY2xpZW50X2lkIjoiYjRmNzBjN2QtZWE4Yi00MjNmLWEwOWItNzg1ZmI0NTgwOTY5In0.qsjbnSEpbsmDqPV_LXn4Rz2o7-fo4SHbCR6n1XyXUiyI0XrYxs7xWjsQ0vi4gSKjGa36J3qmdciZL3KqwNCfx_J0DdV19JsQmg0x12GrEFNlo5v6Vt00lF_jt28Vfclslm3zttuzFm9aiK6iosGHfrF1pYqMrgQTT_wAsLgIz35BMbksvPt21H08cm-vf0xFTw9vequ97hsYktveZ4dzKnIp-voPs0Nz4_AkL-0W91T2_bqGlmv4crWVe_Io5P-iB84wetFQb3XhtlUgQLT23EGInELUU_4z9qPhyQ8htKloUfOX3coql9QCmREGiQTidMswvDEPnlDJLOncb3944w",
    "token_type": "bearer",
    "refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0MTFlYzA2NS03NDI2LTRjYjQtYWNjNC1jZGUwNzhlNTU4MjkiLCJpc3MiOiJodHRwczovL2FwaS1ldS5wcmVwcm9kLmRlY2F0aGxvbi5uZXQvY29ubmVjdCIsImRhdGFfY2VudGVyIjoiRVUiLCJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwiY2xpZW50X2lkIjoiYjRmNzBjN2QtZWE4Yi00MjNmLWEwOWItNzg1ZmI0NTgwOTY5IiwiYXV0aF90aW1lIjoxNjc5NTcxNDIyLCJzY29wZSI6WyJwcm9maWxlOndyaXRlIiwiZW1haWw6d3JpdGUiLCJnZW5kZXIiLCJwaG9uZSIsIm9wZW5pZCIsInByb2ZpbGUiLCJlbWFpbCIsImNvbnRhY3RzIiwiY29udGFjdHM6d3JpdGUiXSwiYXRpIjoiQlo2M013VzVfc0xOLUh6MDZJQXBySWRMeFNvIiwicGVyc29uaWQiOiI5OTAxNjEyNjgxOSIsImxvY2F0aW9uIjoiRlIiLCJleHAiOjE2OTUzODI2MjksImlhdCI6MTY3OTU3MTQyOSwianRpIjoiRDhuVzJrQjFmTXh5TmhBcEl6M04yT1FydENFIn0.IfUBM493lZAhTxVVLT6kXfEHVi4SJCV-JZNCXk-iI_QP92h-wP9bRbV2lDL1VNsVyVedfG4HlwNxAc90K9ZnCenHby-R-xYfXB-2747iu373KWPfwcGAhYO5Lm1Ok9Ao-wI7r5XfI20PnarA8XpxKW03sTsGE7RIWLHsdvH5srMJxakViGUFBPHMBH8RHSdhGEj4rP-1mIzWeAQp69Ce8h0Psjp4a082FTp1Bj8mtP12wMxLqoMwvyL_z8dLbXtNQsmHVh-c4322Ac8BliTZBnHGFWROSEKE6FSIbrxI_sCg9Hhnv-VAEQGxgL7yRoDFfA4vQraWFikN7KqIxTIR4w",
    "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0MTFlYzA2NS03NDI2LTRjYjQtYWNjNC1jZGUwNzhlNTU4MjkiLCJhdWQiOlsiYjRmNzBjN2QtZWE4Yi00MjNmLWEwOWItNzg1ZmI0NTgwOTY5Il0sImF6cCI6ImI0ZjcwYzdkLWVhOGItNDIzZi1hMDliLTc4NWZiNDU4MDk2OSIsImF1dGhfdGltZSI6MTY3OTU3MTQyMiwiaXNzIjoiaHR0cHM6Ly9hcGktZXUucHJlcHJvZC5kZWNhdGhsb24ubmV0L2Nvbm5lY3QiLCJleHAiOjE2Nzk1NzIzMjksImlhdCI6MTY3OTU3MTQyOSwianRpIjoiSUQuRXZ3N0dibkZoN2lCYWpTV2VoUFlucGh6UHhBIn0.ebHJVKBG3aXYOWE3d8T-Uf_FEf9KsW7qcGsjjzch4LUJSzWoEGFwPMYOSGQAU9s_4EmNwc45tHS6wmq3jxunBgBACzhzUeQV3h_L51QMk7d0C6SkR4Dz4Aa5vPTslhUdKcuKnCguNUseH0Ao3KkO1MqtkyDq6YK491cMwJoHiDicA64aJwKe8rmxPLPBMKi4QIuMXRHBJgq99LwrwP4qfu0Nq_X-uVF8phr4Tw_sySMKam9HEGqziNBU97KNRuNeHgzSjdhGXXx0mYAQQ8ybS33Q0fol500Nj-FfJrnkfPjOkma2TUHfrU1IuHIL0p5177lbbGzsRjqbOtF8v9Z50A",
    "expires_in": 899,
    "scope": "profile:write email:write gender phone openid profile email contacts contacts:write",
    "jti": "BZ63MwW5_sLN-Hz06IAprIdLxSo"
}
                                            

Using Postman

You can use Postman to try the flow on your computer

You need to disable the "Automatically follow redirects" option in the Postman settings.

Postman settings


Tip

You can set the following code in the Tests tab of Postman in the step 4, it will extract the code from the Location header in the response and store it in a environment variable.


pm.test("Extract code", function () {
    // Extract code
    let location = postman.getResponseHeader('Location');
    let regex = '^https.+code=(.+)&.+';//match code=xxx
    let code = location.match(regex)[1];

    pm.environment.set('code', code);
});
                                        
Terms & Services