This is a POC that demonstrates A solution to provide a layer on the front of the Client-side (placed within an API Gateway), to apply some security requirements for the Front End App to be more secure. in terms of communicating with any backend API.
- Docker file that holds the Nginx and njs Modules installation.
- Nginx config
nginx.conf
file ready to use. - njs applications/examples inside the
jsCode.js
that contains the javascript code would be used to achieve our POC. - Exposing 2 Nginx servers (
security_gateway
&backend_side
) that allow us to apply the functionality that we've implemented. - docker-compose to facilitate the development process.
> docker-compose up --build
- Token/Cookie exchange:
We will explain the
token/Cookie
exchange process through the security gateway, Using the njs module as a scripting language to facilitate and allow us to manipulate the request/response by writing somejavascript
functions/callbacks to handle a certainNginx
location/API.
covertTokenToCookie
By the Postman App, you can perform the following API call :-
POST localhost:8086/token
nginx.conf:
location /token{
if ($request_method != 'POST'){
return 405;
}
js_content jsCode.covertTokenToCookie;
}
location /token_proxy {
proxy_pass http://backend_side:8087/token;
proxy_ssl_server_name on;
}
As you can see, we used the js_content
Directive from the ngx_http_js_module. and pass the handler covertTokenToCookie
to it. So that we can control/manipulate the /token_proxy
response. by extracting the response body, then adding its fields as Cookies for the same response.
jsCode.js:
function covertTokenToCookie(r) {
r.subrequest("/token_proxy", { method: "POST" },
function (reply) {
var status = reply.status;
if (status) {
r.log('---debugging||||----')
ngx.log(ngx.INFO, reply.responseBody)
var response = JSON.parse(reply.responseBody);
var cookies = [];
Object.keys(response).forEach(key => {
cookies.push(`${key}=${response[key]}; HttpOnly`);
})
r.headersOut["Set-Cookie"] = cookies;
r.return(status, "success!");//reply.responseBody
} else {
r.return(401);
}
}
);
}
covertCookieToToken
By the Postman App, you can perform the following API call :-
POST localhost:8086/agent_token
Here we will explain the opposite of the prev. example. nginx.conf:
location /agent_token{
if ($request_method != 'POST'){
return 403;
}
js_content jsCode.covertCookieToToken;
}
location /agent_token_proxy{
if ($request_method != 'POST'){
return 403;
}
proxy_pass http://backend_side:8087/agent_token;
proxy_ssl_server_name on;
}
Also, we used the js_content
Directive and passes the handler covertCookieToToken
to it. So that we can manipulate the /agent_token
request. by extracting the Cookies header, then adding them as a request body for the agent_token_proxy
API.
jsCode.js:
function covertCookieToToken(r) {
var cookies = r.headersIn["Cookie"]; //r.requestBody
if (cookies) {
var body = JSON.stringify(parseCookiesToJSON(cookies));
r.log(`body is --->${typeof body} , ${body}`);
r.subrequest("/agent_token_proxy", { method: "POST", body }, function (reply) {
var status = reply.status;
r.return(status, reply.responseBody);
})
} else {
r.return(400);
}
}
MIT