cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

CSRF Token Fetching for Python Client - OData Services

punitsigma47
Discoverer
0 Likes
4,283

I am trying to use Python requests library to fetch the csrf token for an OData service using GET request (code stub below). However the response header doesnt have any flag corresponding to csrf token value.

This would subsequently be used for doing a POST on one of the tables but the token validation fails.

I tried using Postman and it successfully generates csrf token in response header.

OUTPUT:

Cookies<RequestsCookieJar[<Cookie sap-usercontext=sap-client=3xx for xx.de/>, <Cookie SAP_SESSIONID_xx_3xx=mBhtGO6hrFCr4PZ6iuvvWp11712FTxHtuZRFfWVfZdw%3d for xx.de/>]>

Response Header

{'set-cookie': 'sap-usercontext=sap-client=3xx; path=/, SAP_SESSIONID_xx_3xx=VdUUsfqf19sYMFW3jmRDLWajmUWFSRHtttlFfWVfZdw%3d; path=/; HttpOnly', 'content-type': 'application/xml', 'content-length': '889', 'dataserviceversion': '1.0', 'sap-server': 'true', 'sap-perf-fesrec': '74990.000000'}

Session Header

{'User-Agent': 'python-requests/2.28.1', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}

import requests
import json
url="http://url/sap/opu/odata/sap/Service/EntitySet/$format=xml"

sess = requests.session()
sess.headers.update({'Connection': 'keep-alive'})
params= { 'x-csrf-token': 'Fetch' }
r = sess.get(url,auth=(uname,pass),params=params)
token = r.headers
print(r.cookies)
print(token)
print(sess.headers)

Accepted Solutions (0)

Answers (1)

Answers (1)

former_member876434
Discoverer
0 Likes

Hi Punit,

Please pass this header to get the 'x-csrf-token' in response header. I am attaching the code snippet below for your reference.

Regards,

Anim

## CSRF TOken Fetch###
csrf_sess = requests.session()
csrf_sess.headers.update({'connection':'keep-alive'})
header = {
    'x-csrf-token':'fetch',
    'Authorization':f'Basic {base64.b64encode(f"{username}:{password}".encode()).decode()}',
    'Content-Type':'application/json'
}
csrf_url = f"{base_url}/sap/c4c/odata/v1/c4codataapi/ServiceRequestCollection"
csrf_params = {'x-csrf-token':'fetch'}
csrf_call = csrf_sess.get(csrf_url,params=csrf_params,headers=header)

token_header = csrf_call.headers
csrf_token = token_header['x-csrf-token']
print(token_header)
print(token_header['x-csrf-token'])