Home > Mobile >  Encode parameter before executing the request
Encode parameter before executing the request

Time:09-30

We are using .NET Core 3.1 and Swashbuckle.AspNetCore 5.6.3.

Some of our controller actions require User-Identity HTTP header to be sent in the request. The value of this User-Identity HTTP header is base64-encoded JSON object. Example:

JSON object

{
  "email": "[email protected]"
}

is encoded in base64 as:

ewogICJFbWFpbCI6ICJ0ZXN0QHRlc3QuY29tIgp9.

We implemented the following filter operation which checks if controller action has [RequireUserIdentityFilterAttribute] attribute and adds a parameter accordingly.

public class RequireUserIdentityOperationFilter : IOperationFilter
{
  public void Apply(OpenApiOperation operation, OperationFilterContext context)
  {
    // check if controller action has RequireUserIdentityFilterAttribute with reflection
    var hasRequireUserIdentityFilterAttribute = context.MethodInfo
      .GetCustomAttributes(true)
      .OfType<RequireUserIdentityFilterAttribute>()
      .Any();

    if (hasRequireUserIdentityFilterAttribute)
    {
      operation.Parameters.Add(new OpenApiParameter
      {
        Description = "Base-64 encoded user email object. Example: { \"Email\": \"[email protected]\" } => ewogICJFbWFpbCI6ICJ0ZXN0QHRlc3QuY29tIgp9",
        Name = "User-Identity",
        In = ParameterLocation.Header,
        Schema = new OpenApiSchema
        {
          Type = "string",
          Example = new OpenApiString("ewogICJFbWFpbCI6ICJ0ZXN0QHRlc3QuY29tIgp9")
        }
      });
    }
  }
}

This is how it looks like in SwaggerUI:

image

It works fine as-is. User-Identity header is sent to the server.

However, it is not very user-friendly because user has to input a string which must be base64-encoded. Is it possible that we simplify the input so that the user will only have to input user email (ex. [email protected]) and C# will handle the base64 encoding before the request is sent to the server?

CodePudding user response:

SwaggerUI uses JavaScript to send the requests to the server. You could inject a script that intercepts the request and changes the header before transmitting it to the server, e.g.

app.UseSwaggerUI(c =>
{
    // ...
    var adjustHeaders = @"(request) => {
        let header = request.headers["User-Identity"];
        if (header && header.length > 0) {
          // header is a JSON object
          if (header[0] == "{") header = 
            btoa(header);
          // header is an email address
          else if (header.indexOf("@") >= 0) 
            header = btoa(JSON.stringify({ email: header }));
          // Otherwise assume that it is already encoded
          request.headers["User-Identity"] = header;
        }
        return request;
    }";
    c.UseRequestInterceptor(adjustHeaders);
});

Above script is a pseudo-Javascript that can give you a starting point. Please test it in the browser whether it works in your situation and for the browsers your SwaggerUI targets.

  • Related