Adding Access-Control-Max-Age to Azure Functions - azure

In order to prevent OPTIONS preflight requests being sent to an Azure Function, I want to add the Access-Control-Max-Age header to the OPTIONS response so that the browser caches the response for a given time.
I tried to create an Azure Proxy Function with this proxies.json file:
{
"proxies": {
"AddCacheHeaderToCorsPreflightResponse": {
"debug": true,
"matchCondition": {
"methods": [
"OPTIONS",
"GET"
],
"route": "/api/{rest}"
},
"backendUri": "http://%WEBSITE_HOSTNAME%/api/{rest}",
"responseOverrides": {
"response.headers.Access-Control-Max-Age": "31536000"
}
}
}
}
But this fails to add the response header to the OPTIONS request, but, for testing purposes, I can get GET responses to return the header. It appears that Azure doesn't allow you to add proxy functions for OPTIONS requests.
Is there a way to do this in Azure?

You need to make sure that your function.json contains OPTIONS in the methods array, like so:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": ["get", "post", "options"]
}
]
}
When you configure your httptrigger function, click Integrate and choose the OPTIONS method. Alternatively, you can remove the methods array entirely and allow all methods.

Related

Additional Parameter in Node Azure Function

I am just starting to learn to implement Azure Functions with NodeJS and i am trying to add additional custom parameters to the trigger function
as this is the recommended way for input bindings by Microsoft, but I can't get it to work.
I am getting a 404 Not Found Error.
When I remove the id Object from the function.json, the function works, but the id is undefined.
I tried to call the function with get and id as query param and as post with the { id: 123 } in the body, but with no success.
Can anyone help out?
Thanks in advance.
index.ts
const httpTrigger: AzureFunction = async function (
context: Context,
req: HttpRequest,
id: string
): Promise<void> {
context.log("HTTP trigger function processed a request with id.", id);
context.res = {
body: {
id,
},
contentType: "application/json",
};
};
function.json
{
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post"
]
},
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "id",
"methods": [
"get",
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
}
],
"scriptFile": "../dist/respository/index.js"
}
In Node js Azure function we don’t have an Attributes and Annotations so we cannot add additional parameters in azure functions. Attributes are not supported by JavaScript.
In Azure function C# class libraries and Java, the HttpTrigger attribute is available to configure the function.
You can set the authorization level and allowable HTTP methods in attribute constructor parameters, webhook type, and a route template. For more information about these settings, see configuration.
Refer here

How can i query data from my azure cosmos db?

I have azure functions written in nodejs. I can't find a way how to get data for example from my created azure cosmos db. I know that there is azure cosmos SDK, but i don't want to use that way.I want to learn to do it through the azure functions because it is possible with them also.
i try do to this:
function.json
{
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"type": "cosmosDB",
"name": "inputDocument",
"databaseName": "dbtodos",
"collectionName": "items",
"connectionStringSetting": "todos_DOCUMENTDB",
"partitionKey": "/all",
"direction": "in"
}
],
"disabled": false
}
index
module.exports = async function (context, req) {
context.res = {
// status: 200, /* Defaults to 200 */
body: context.bindings.inputDocument
};
};
after my deploy when i visit the automatically generated url - i can't even open the link.There is not requests coming back.
If i do some basic example where i don't try to pull data from the db then my url is working after deploy.
How can i get the data ?
My data in the local.settings.json was wrong. I had azure storage for other table not for the one that i wanted to query... The code works perfectly fine

What is the correct way to handle multiple HTTP Methods in Azure Functions (NodeJS)

When building an application in Azure Functions you can specify the HTTP Methods that are accepted in the function.json
Given an API that you can do multiple functions on (GET, PUT POST etc) what is the best way to create that function or functions.
There will be shared logic and libraries that need to be available, so I'm looking for a pattern that can enable all the MEthods in a single class, but not sure how you would define that in a function.json such that each HTTP Method could have its own entry point.
The other option is to create a function that basically chooses the method and class that function but this seems like some middleware overhead that I"m sure can be handled in a better way.
i.e. I don't think I should do this for every object that I create a function for and there must be a better pattern.
async HandleRequest(){
return validateJwt(function(context,req){
if(req.method === 'GET'){
}
else if(req.method === 'POST'){
}
else if(req.method === 'DELETE'){
}
else if(req.method === 'PUT'){
}
else if(req.method === 'PATCH'){
}
});
}
So the best method for this is to use multiple functions.
You can define functions by route and method in the function.json file.
see the example.
Notice route:family/{id:int} this is the only route that this function will handle. you also put in the "methods": ["get"] To restrict the function to a GET.
Create a function per METHOD to have more maintainability in your code. I then use some middleware functionality (which does auth and error handling) before I have a common FamilyHandler Class that does the CRUD operations, including managing the connection to the database.
{
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": ["get"],
"route": "family/{id:int}"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
I discovered this in the following documentation https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-http-webhook-trigger?tabs=javascript
Your function.json should like this:
{
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
By default, if methods is not specified, then the function accepts all methods.

When I am running azure HTTP Trigger function i am getting 401 unauthorized

I am trying to run Azure HTTP Trigger Azure Function and I am receiving a 401 Unauthorized. It was working fine for me earlier.
When I created the new function under the same Function App and copied the same code then also it is running fine but when I am trying to run my created function then I am getting the same error that I mentioned.
I'm seeing the following logs in the streaming service.
2018-07-02T07:09:41 Welcome, you are now connected to log-streaming service.
2018-07-02T07:09:48.893 [Info] Executing HTTP request: {
"requestId": "53e54698-c46b-4cb6-9ed0-d042eaf9ec71",
"method": "POST",
"uri": "/api/Source/MPAA/false"
}
2018-07-02T07:09:48.893 [Info] Executed HTTP request: {
"requestId": "53e54698-c46b-4cb6-9ed0-d042eaf9ec71",
"method": "POST",
"uri": "/api/Source/MPAA/false",
"authorizationLevel": "Anonymous",
"status": "Unauthorized"
}
This is how I solved the problem based on the cause correctly provided by Nick above. Do this if you don't want to have to open the Azure Function's GUI every time you push your code.
In the source code of the function:
[FunctionName("YourFunctionName")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log){
What I had to do was to change the default setting AuthorizationLevel.Function into AuthorizationLevel.Anonymous. The former only allows triggering from other Function apps, the later will let you trigger from the browser.
If you are managing your code via the azure portal, then simply navigate to "Integrate" and change the "Authorization Level" drop-down to "Anonymous".
If you are managing your code with source control integration (e.g. via git), add this to your function.json:
"authLevel": "anonymous"
Full snippet of function.json:
{
"bindings": [
{
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [ "post" ],
"route": "Source/MPAA",
"authLevel": "anonymous"
},
{
"type": "http",
"name": "res",
"direction": "out"
}
],
"disabled": false
}
Note: the above is just an example, you may have to tweak the route.
Note: the /api is the default prefix, and can be modified in the host.json file.
Its about the authlevel of the function.
If you use the authlevel = anonymous in you function.json file. Then you don't have to pass any access key and you can access the azure function api like the normal api endpoints.
{
"disabled": false,
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
For example you http trigger is http://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME> you can easily access this without any access/auth key.
If your are using the authlevel = function then you have to pass the access key/Api key with the http trigger endpoint while hitting it. If you don't you will get the 401 unauthorized.
{
"disabled": false,
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
You need to pass the key like as below example.
**https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>?code=<API_KEY>
**
For the authlevel = function you can access the http trigger by the function key
and the host key. You will find the Get Function Url section when you open the function in the azure portal.
Note
With the host key you can access all of your http trigger endpoints its going to be common for all the http trigger. But the function key is unique for every function.
The third option is to use the authlevel = admin.
{
"disabled": false,
"bindings": [
{
"authLevel": "admin",
"type": "httpTrigger",
"direction": "in",
"name": "req"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
For auth level admin the http trigger can only be access by the master key.
**https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>?code=<MASTER_KEY>
**
You will find all these keys as per the auth levels in the Get Function Url section.
The complete guide for the authlevel is in this link.
Azure Functions HTTP trigger function authlevel Explanation
I hope this will be helpfull.
I started getting 401's too until I realised that I had two functions with the same route. That obviously confused Azure big time.
Check if you don't have different functions with same routes.
I started seeing this response after changing the function runtime version via Azure Portal. Redeploying the function app from Visual Studio resolved the issue for me.

How to customize Azure function url

Just got started with azure functions. I am using it as an httptrigger for an IoT device.
I am trying to setup one function that will work for httptrigger requests coming from several IoT devices - So I dont have to setup one function per device. So ideally, in my c# file, I will have something like this:
DeviceClient deviceClient;
string iotHubUri = "myhub";
string deviceName = "something dynamic here that changes with device";
string deviceKey = "something dynamic here that changes with device";
Then , I'd like to get my function url to look something like this:
"https://<functionapp>.azurewebsites.net/api/<function>/{device_id}?code=xxxxx"
where device_id is the IoT device id.
I am not sure how to first setup the reference in the c# file to be dynamic and also how to get the url to look the way I intend.
Some help will be appreciated. Thanks
There is a route parameter is HTTP trigger exactly for this. Your trigger definition should look something like this:
"bindings": [
{
"type": "httpTrigger",
"route": "something/{deviceid}",
"name": "request",
// possibly other parameters
}
],
If you are using precompiled C# functions, you can do the same via attribute property, e.g.
public static IActionResult Run(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "something/{deviceid}")]
HttpRequest request,
string deviceid)
{
// do something based on device id
}
Customize your Azure function route
To customize your url you can use two files, the one in which is defined the function function.json and the host.json.
function.json suffix
in function.json you can define the base url adding to the bindings array the "route": "yourbaseurl" property. that should result in something like this
{
"scriptFile": "../dist/server.js",
"disabled": false,
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"route": "cool", ///// This is the line that you have to add /////
"methods": [
"get",
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "$return"
}
]
}
host.json prefix
On the host.jsonfile you can add a prefix to that route, let's say you want to add a fancy name group or so...
therefore your file should look something like this
{
"version": "2.0",
"extensions": {
"http": {
"routePrefix": "prefix" ///// here is that you include your prefix route /////
}
},
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[1.*, 2.0.0)"
}
}
I just want one word or none
if you want to have just one word in your route leave the host.json "routePrefix": "" and the function.json "route": "therouteyouwant" or empty like "route": "".

Resources