ini Nginx Lua脚本redis基于基本用户身份验证

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ini Nginx Lua脚本redis基于基本用户身份验证相关的知识,希望对你有一定的参考价值。

function password_encode(password)
    local bcrypt = require 'bcrypt'
    return bcrypt.digest(password, 12)
end

function check_password(password, encoded_password)
    local bcrypt = require 'bcrypt'  
    return bcrypt.verify(password, encoded_password)
end


function get_user(username)
    --- Defaults

    local access_redis_host =  ngx.var.access_redis_host == ''
        and '127.0.0.1' or ngx.var.access_redis_host

    local access_redis_port = ngx.var.access_redis_port == ''
        and 6379 or ngx.var.access_redis_port

    local access_user_catalogue = ngx.var.access_user_catalogue == ''
        and 'nginx_catalogue:users' or ngx.var.access_user_catalogue

    --- 

    local redis = require "nginx.redis"
    local red = redis:new()

    red:set_timeout(1000)

    local ok, err = red:connect(access_redis_host, access_redis_port)
        if not ok then
            ngx.log(ngx.ERR, "failed to connect to the redis server: ", err)
            ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
        return
    end

    local res, err = red:hget(access_user_catalogue, username)

    if not res then
        ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
        return
    end

    -- User is not found
    if res == ngx.null then
        return
    end

    return res
end


function authenticate()
    -- Test Authentication header is set and with a value
    local header = ngx.req.get_headers()['Authorization']
    if header == nil or header:find(" ") == nil then
        return false
    end

    local divider = header:find(' ')
    if header:sub(0, divider-1) ~= 'Basic' then
       return false
    end

    local auth = ngx.decode_base64(header:sub(divider+1))
    if auth == nil or auth:find(':') == nil then
        return false
    end

    divider = auth:find(':')
    local username = auth:sub(0, divider-1)
    local password = auth:sub(divider+1)

    local res = get_user(username)

    if res == nil then
        return false
    end

    if check_password(password, res) then
        return true
    end

    return false
end


local user = authenticate()


if not user then
   ngx.header.content_type = 'text/plain'
   ngx.header.www_authenticate = 'Basic realm=""'
   ngx.status = ngx.HTTP_UNAUTHORIZED
   ngx.say('401 Access Denied')
end
server {
  listen 80;
  server_name _;
  root /var/www/html;

  location / {
    set $access_redis_host '127.0.0.1'; 
    set $access_redis_port 6379; 
    set $access_user_catalogue 'myapp:users';

    access_by_lua_file access.lua;
  }
}

以上是关于ini Nginx Lua脚本redis基于基本用户身份验证的主要内容,如果未能解决你的问题,请参考以下文章

ini 使用lua脚本的简单nginx配置

Nginx + Lua + redis (转)

Redis入门 - Lua脚本

基于 Redis 实现分布式锁,分析解决锁误删情况 及 利用Lua脚本解决原子性问题并改造锁

基于Nginx+Lua改进多级缓存

Redis 多次调用 vs lua 脚本