redis2-nginx-module icon indicating copy to clipboard operation
redis2-nginx-module copied to clipboard

Authentication Support

Open vinay-nadig-0042 opened this issue 10 years ago • 6 comments

Hello,

Is password authentication supported by this module? I could not find anything in the docs for this. I am trying to connect to a rediscloud endpoint:

redis://redistogo:[email protected]:9797

Thanks.

vinay-nadig-0042 avatar Feb 20 '15 05:02 vinay-nadig-0042

@hobblegobber Just use redis's auth command for it:

http://redis.io/commands/AUTH

All redis's commands are supported. So I don't want to repeat the official redis command manual in this module's documentation.

agentzh avatar Feb 20 '15 20:02 agentzh

这样的话,每一次请求都得验证一下密码,性能会不会有所下降

bjdgyc avatar Apr 29 '16 09:04 bjdgyc

@bjdgyc That's why you should really use ngx_lua and the lua-resty-redis library for Redis communication where you have total control over everything.

BTW, this place is considered English only. DO NOT USE CHINESE HERE. If you really want to use Chinese, please join the openresty (Chinese) mailing list instead. Please see https://openresty.org/en/community.html Thanks for your cooperation.

BTW 2: it's also rude to reply to pure English conversations with Chinese.

agentzh avatar Apr 29 '16 20:04 agentzh

Hi: here is my nginx.conf:

 location = /redis2 {
     internal;
     redis2_query auth "mypwd";
     redis2_raw_queries $args $echo_request_body;
     redis2_pass 127.0.0.1:6379;
 }

It could not work fine. it's trouble to write pwd in every echo_request_body { 'auth', 'mypwd'}

wllenyj avatar Mar 08 '17 06:03 wllenyj

Hi: here is my nginx.conf:

 location = /redis2 {
     internal;
     redis2_query auth "mypwd";
     redis2_raw_queries $args $echo_request_body;
     redis2_pass 127.0.0.1:6379;
 }

It could not work fine. it's trouble to write pwd in every echo_request_body { 'auth', 'mypwd'}

A late answer to remind others: Because redis2_query and redis2_raw_queries are independent of each other. You can't get HTTP pipelined from them. When you used redis2_query auth your redis password and return res : +OK\r\n Nginx or Redis did't save this auth status. And then redis2_raw_queries will create new subrequest to get/set your key and return error res : NOAUTH Authentication required

Put my solution: Get key from redis in nginx.conf:

http {
    server {
    	location = /database {
	        internal;
	        redis2_raw_queries 2 "auth password\r\nget key\r\n";
	        redis2_pxory 127.0.0.1:6379;
	    }
	}
}

Set key to redis in nginx.conf:

http {
    server {
    	location = /database {
	        internal;
	        redis2_raw_queries 2 "auth password\r\nset key value\r\n";
	        redis2_pxory 127.0.0.1:6379;
	    }
	}
}

zhyonc avatar Mar 23 '22 07:03 zhyonc

Complete example: nginx.conf file:

load_module modules/ngx_http_js_module.so;
load_module modules/ngx_http_redis2_module.so;
stream {
    upstream redis {
        server 127.0.0.1:6379;
    }
    server {
        listen 1024;
        proxy_connect_timeout 10s;
        proxy_timeout 30s;
        proxy_pass redis;
    }
}
http {

    js_import http.js;

    server {
        location / {
            js_content http.process;
        }
        location = /database {
            internal;
            redis2_raw_queries 2 $query_string;
            redis2_pass 127.0.0.1:1024;
        }
    }
}

http.js file:

'use strict';

async function process(r) {
    // For CORS
    r.headersOut['Access-Control-Allow-Origin'] = '*';
    r.headersOut['Access-Control-Allow-Headers'] = 'Content-Type';
    r.headersOut['Access-Control-Max-Age'] = '600';
    if (r.method == 'OPTIONS') {
        r.return(200, "OK");
        return;
    }
    // Deserialize JSON
    let type, password, key, value;
    try {
        let data = JSON.parse(r.requestText);
        type = data["type"];
        password = data["password"];
        key = "name";
        value = data[key];
        if (!type || !password || !key || !value) {
            throw new TypeError("Bad Request");
        }
    } catch (e) {
        r.error(e);
        r.return(400, e);
        return;
    }
    // Get or Set Data
    let reply = "";
    switch (data["type"]) {
        case 'Get':
            reply = await query(r, password, key);
            reply = JSON.stringify(reply);
            r.headersOut['Content-Type'] = 'application/json';
            break;
        case 'Set':
            reply = await update(r, password, key, value);
            r.headersOut['Content-Type'] = 'application/text';
            break;
        default:
            r.headersOut['Content-Type'] = 'application/text';
            r.return(404, 'Not Found');
            return;
    }
    r.return(200, reply);
}

async function query(r, password, key) {
    try {
        let response = await r.subrequest('/database', `auth ${password}\r\nget ${key}\r\n`);
        if (response.status == 200) {
            let res = response.responseText.split('\r\n');
            if (res[0] != '+OK') {
                throw new Error('auth fail');
            }
            if (res[1] != '$-1') {
                return res[2];
            }
        }
    } catch (e) {
        r.error(e);
    }
    return '{}';
}

async function update(r, password, key, value) {
    try {
        let response = await r.subrequest('/database', `auth ${password}\r\nset ${key} '${value}'\r\n`);
        if (response.status == 200) {
            let res = response.responseText.split('\r\n');
            if (res[0] != '+OK') {
                throw new Error('auth fail');
            }
            return res[1];
        }
    } catch (e) {
        r.error(e);
    }
    return "";
}

export default { process };

Client Post JSON:

{
    "type": "Get",
    "password": "123456",
    "name":{}
}

{
    "type": "Set",
    "password": "123456",
    "name":
    {
        "first": "zhyon",
        "last": "chen"
    }
}

zhyonc avatar Mar 23 '22 08:03 zhyonc