I am using Google App Engine's Protocol RPC library. I want to get the headers for a request and check that a certain header exists. I can't figure out how to get the requests headers?
The code basically looks like this:
class MyService(remote.Service):
#remote.method(MyRequest, MyResponse)
def my_request(self, request):
# TODO: Check that header exists in request
The passed in request object is of the type 'MyRequest' and doesn't have any header information attached to it.
There is a special method initialize_request_state that allows you to access all of the requests headers.
class MyService(remote.Service):
def initialize_request_state(self, state):
self.headers = state.headers
#remote.method(MyRequest, MyResponse)
def my_request(self, request):
logging.debug(self.headers)
Related
I am trying to implement a type of custom authentication by using aiohttp something like the example in this link but I also need request body. Here is an example for requests:
class CustomAuth(AuthBase):
def __init__(self, secretkey):
self.secretkey = secretkey
def get_hash(self, request):
if request.body:
data = request.body.decode('utf-8')
else:
data = "{}"
signature = hmac.new(
str.encode(self.secretkey),
msg=str.encode(data),
digestmod=hashlib.sha256
).hexdigest().upper()
return signature
def __call__(self, request):
request.headers["CUSTOM-AUTH"] = self.get_hash(request)
return request
I've looked into tracing and BasicAuth but they are useless in my situation. On on_request_start request body is not ready, on on_request_chunk_sent headers have already been sent. A solution like BasicAuth don't have access the request data at all.
Do you have any idea?
Thanks in advance.
I would need some of your help adapting Authlib with Django.
I'm trying to develop a Django app using OpenId and Authlib to connect my users and facing an issue with the access token, the issue invalid_client occurs. Using Postman I found out that the OpenId provider needs some parameters in the Header like 'Content-Length' or 'Host'.
When the Header param is defined in client.py, it works like a charm. However, I'd like to pass the custom header from views.py (mostly to avoid defining the Host directly in the package), but authorize_access_token doesn't allow multiple arguments,
def auth(request):
token = oauth.customprovider.authorize_access_token(request)
Maybe the "Compliance Fix for non Standard" feature might help, but I wasn't able to adapt it for Django and the Header parameter
https://docs.authlib.org/en/stable/client/oauth2.html#compliance-fix-oauth2
from authlib.common.urls import add_params_to_uri, url_decode
def _non_compliant_param_name(url, headers, data):
params = {'site': 'stackoverflow'}
url = add_params_to_uri(url, params)
return url, headers, body
def _fix_token_response(resp):
data = dict(url_decode(resp.text))
data['token_type'] = 'Bearer'
data['expires_in'] = int(data['expires'])
resp.json = lambda: data
return resp
session.register_compliance_hook(
'protected_request', _non_compliant_param_name)
session.register_compliance_hook(
'access_token_response', _fix_token_response)
Does anyone know a way to pass a custom Header to Authlib or defining it using the Compliance Fix and Django?
I had to do this recently for a provider that required an Authorization header added to the the refresh token. Here is the code I used.
Add the register_compliance_hook inside the function that is called using the compliance_fix argument when initializing the service.
def _compliance_fixes(session):
def _add_header_refresh(url, headers, body):
headers.update({'Authorization': "Basic " + self.secret_client_key})
return url, headers, body
session.register_compliance_hook('refresh_token_request', _add_header_refresh)
oauth = OAuth()
oauth.register("oauth-service", compliance_fix=_compliance_fixes)
I'm using the requests-oauthlib library to get a request token from an OAuth (v1) provider.
oauth = OAuth1Session(CONSUMER_KEY, client_secret=CONSUMER_SECRET,
signature_method=SIGNATURE_HMAC,
signature_type=SIGNATURE_TYPE_AUTH_HEADER)
resp = oauth.fetch_request_token(url=REQUEST_TOKEN_URL)
I'd like to send a custom User-Agent header with the request token fetch request and include some contact information in case there are ever any problems with my script. Can this be done?
It's possible to pass in a client class to the OAuth1Session constructor. From the docblock in the relevant file:
"""
:param client_class: A subclass of `oauthlib.oauth1.Client` to use with
`requests_oauthlib.OAuth1` instead of the default
"""
Within the oauthlib.oauth1.Client class, the _render(self, request, formencode=False, realm=None) method appears responsible for preparing the request. Since unrelated headers don't impact the base string that the request signature is created from, adding a new header/changing an existing User-Agent header shouldn't cause the signature to change in any way.
As such, we can create a custom client class, override the _render method and call the implementation in the parent class once we've added our header:
class CustomClient(Client):
def _render(self, request, formencode=False, realm=None):
request.headers['User-Agent'] = "FooClient/1.0"
return super()._render(request, formencode, realm)
The code that instantiates OAuth1Session then simply needs to reference the above class:
oauth = OAuth1Session(CONSUMER_KEY, client_secret=CONSUMER_SECRET,
signature_method=SIGNATURE_HMAC,
signature_type=SIGNATURE_TYPE_AUTH_HEADER, client_class=CustomClient)
I need to know the date/time of client requests.
[I suppose] these informations are embeded in header part of post http requests.
So, how do I get them in a webapp2.RequestHandler class?
class GetPostHeaderFields(webapp2.RequestHandler):
def post(self):
<date or time or datetime whatever> = ???
Tanks for any help.
It depends on the framework you are using. In case of webapp2 it is available as a dictionary object in request.headers . See link
class MyHandler(webapp2.RequestHandler):
def post(self):
name = self.request.get('name')
#Access request headers here
request.headers['Cookie'] = 'test=value' #Could be anything like Authorization, etc
In case of Django you can access it as a dictionary object in request.META, See here
I need a library that can only format a correct HTTP response (without creating a web server because I already have this one).
I have to pass a body of an http response and a content type to this library.
The following function does not work properly if I try to send AJAX - jQuery does not find any response. However if I type a corresponding URL in the URL string of browser then a page is displayed.
def response( data ):
return "HTTP/1.0 200 OK\r\nContent-Type:application/json\r\nConnection:close\r\n\r\n{0}\r\n".format( data )
Details. The data variable is string of json. I also use the SocketServer class, call self.request.sendall( result_response ) in child's handle() function.
# the 'request handler' class
class StateRequestHandler( SocketServer.BaseRequestHandler ):
def handle( self ):
...
self.request.sendall( response( some_json ) )
# the configured server class
class StateServer( SocketServer.ThreadingMixIn, SocketServer.TCPServer ):
pass
Solved. The reason was in cross-domain requests.
Try the following:
Although the HTTP 1.0 and 1.1 spec say that a white space is optional between the header name and header value, the specs do say "a single SP[ace] is preferred".
Ensure that you do not have any Cross Domain issues so ensure your HTML page is served from exactly the domain,scheme and port as your JSON response (Unless you've correctly configured CORS.
Use Chrome Dev Tools / Firebug / Fiddler to see what request they're making and check the Javascript console.
Use Wireshark to see exactly what's on the wire.