MarketSquare / robotframework-requests

Robot Framework keyword library wrapper for requests

Home Page:http://marketsquare.github.io/robotframework-requests/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`Update Session` don't overwrite the authentification

jesusfj710 opened this issue · comments

Hello there,

Today I was struggling with one problem that I thinks is happening in the library.

If we check the first one case, I use one keyword in order to get a token and then, try to set as header in the same session. This will not work, and for me it is strange. If you check the execution of the Keyword to get the response of the get on carriers/findAll you will get a header with the basic auth, but no with the token set as bearer. Not even set as header.

But if you go to the second case, were you create a new session instead, it will work. I know that when you create the new session, you are passing the token as header, but I think that the merge of the header/auth is not done correctly.

wrongOne.robot

*** Settings ***
Library           RequestsLibrary

*** Test Cases ***
Test One
    [Documentation]    POC
    [Tags]    TestOne
    Set Session One    session    url
    ${response}=    Get On Session    session    carriers/findAll

*** Keywords ***
Set Session One
    [Arguments]    ${sessionAlias}    ${DS_API_URL}
    ${basicAuth}=    Create List    client_id    client_secret
    Create Session    ${sessionAlias}    ${DS_API_URL}    auth=${basicAuth}
    ${data}=    Create Dictionary    grant_type=password    username=username    password=password
    ${response}=    Post On Session    ${sessionAlias}    /oauth/token    data=${data}
    Request Should Be Successful    ${response}
    ${tokenClient}=    Set Variable    ${response.json()['access_token']}
    ${tokenHeader}=    Create Dictionary    Authorization=Bearer ${tokenClient}
    Update Session    ${sessionAlias}    headers=${tokenHeader}

goodOne.robot

*** Settings ***
Library           RequestsLibrary

*** Test Cases ***
Test Two
    [Documentation]    POC
    [Tags]    TestTwo
    Set Session Two    session    url
    ${response}=    Get On Session    session    carriers/findAll

*** Keywords ***
Set Session Two
    [Arguments]    ${sessionAlias}    ${DS_API_URL}
    ${basicAuth}=    Create List    dsp    password
    Create Session    ${sessionAlias}    ${DS_API_URL}    auth=${basicAuth}
    ${data}=    Create Dictionary    grant_type=password    username=jesus.fernandez.robotTesterSimonsSuperUser@pivotree.com    password=robotTesterSimonsSuperUser
    ${response}=    Post On Session    ${sessionAlias}    /oauth/token    data=${data}
    Request Should Be Successful    ${response}
    ${tokenClient}=    Set Variable    ${response.json()['access_token']}
    ${tokenHeader}=    Create Dictionary    Authorization=Bearer ${tokenClient}
    Create Session    ${sessionAlias}    ${DS_API_URL}    headers=${tokenHeader}

Hi @jesusfj710 ,

the situation you are facing in wrongOne.robot is not so much due to RequestLibrary, but more so about the requests module itself.

Basically what happens when you

Create Session    alias    url    auth=${basicAuth}

is that you set username and password for the basic authentication to the Session object. auth will be converted to a HTTP basic authentication header by the time the request is made to the server. This header then persists and will not be overwritten by updating the session's headers.

To illustrate what I mean, see the following example:

>>> import requests
>>> ENDPOINT = "http://127.0.0.1:5000/anything"
>>> s = requests.Session()
>>> s.auth = ("user", "pass")
>>> resp = s.get(ENDPOINT)
>>> print("headers: " + repr(resp.request.headers))
headers: {'User-Agent': 'python-requests/2.27.1', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Authorization': 'Basic dXNlcjpwYXNz'}

In the actual request, s.auth is converted to a basic authentication header.

If you try to overwrite this by specifying s.headers, it will be "ignored" (i.e. the authorization header will still have the value of Basic <some base64 string>:

>>> s.headers.update({"Authorization": "Bearer ABCD"})
>>> resp = s.get(ENDPOINT, headers=s.headers)
>>> print("headers: " + repr(resp.request.headers))
headers: {'User-Agent': 'python-requests/2.27.1', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Authorization': 'Basic dXNlcjpwYXNz'}

thank you @robinmatz for the help