这是一个常见的 OpenResty + pgmoon 认证配置问题。以下是完整的解决方案:
1. 检查 PostgreSQL 认证配置
查看 pg_hba.conf
# 找到配置文件位置
psql -U postgres -c "SHOW hba_file;"
# 常见路径:
# /etc/postgresql/*/main/pg_hba.conf
# /var/lib/pgsql/data/pg_hba.conf
修改认证方式(示例)
# pg_hba.conf - 允许密码认证
# TYPE DATABASE USER ADDRESS METHOD
# IPv4 local connections:
host all all 127.0.0.1/32 md5
host all all 192.168.1.0/24 md5
# IPv6 local connections:
host all all ::1/128 md5
# 或者使用 scram-sha-256(更安全)
host all all 0.0.0.0/0 scram-sha-256
重启 PostgreSQL 使配置生效
sudo systemctl reload postgresql
# 或
pg_ctl reload -D /path/to/data/directory
2. OpenResty + pgmoon 正确配置
nginx.conf 中的数据库配置示例
http {
lua_package_path "/path/to/pgmoon/?.lua;;";
upstream database {
postgres_server 127.0.0.1 dbname=mydb user=myuser password=mypassword;
}
server {
location /query {
content_by_lua_block {
local pgmoon = require("pgmoon")
local pg = pgmoon.new({
host = "127.0.0.1",
port = "5432",
database = "mydb",
user = "myuser",
password = "mypassword"
})
local ok, err = pg:connect()
if not ok then
ngx.say("Failed to connect: ", err)
return
end
local res, err = pg:query("SELECT * FROM users WHERE id = " .. ngx.var.arg_id)
if not res then
ngx.say("Failed to query: ", err)
return
end
pg:keepalive()
ngx.say(cjson.encode(res))
}
}
}
}
3. 完整的 Lua 代码示例
connection_pool.lua(推荐使用连接池)
local pgmoon = require("pgmoon")
local cjson = require("cjson")
local _M = {}
function _M.new()
local db_config = {
host = os.getenv("PG_HOST") or "127.0.0.1",
port = os.getenv("PG_PORT") or "5432",
database = os.getenv("PG_DATABASE") or "mydb",
user = os.getenv("PG_USER") or "myuser",
password = os.getenv("PG_PASSWORD") or "mypassword",
-- PostgreSQL 14+ 可能需要指定加密方式
ssl = false,
ssl_verify = false,
pool_size = 20,
backlog = 10,
timeout = 5000, -- 5秒超时
-- PostgreSQL不同版本的认证方法适配
auth_type = 'md5' -- 'md5', 'scram-sha-256', 'trust'
}
return pgmoon.new(db_config)
end
function _M.query(sql, params)
local pg = _M.new()
local ok, err = pg:connect()
if not ok then
return nil, "Connection failed: " .. tostring(err)
end
-- PostgreSQL版本检测和兼容性处理
if params and #params > then
sql=string.gsub(sql,"?","$%d") --参数化查询转换,如果支持的话。
for i,v in ipairs(params) do
params[i]=tostring(v):gsub("'","''")--简单转义,实际应用建议用占位符库如luasql-postgres等。
end
sql=string.format(sql,unpack(params))
end
local res,err=pg:query(sql)
if not res then
pg:close()
return nil,"Query failed:"..tostring(err)
end
--保持连接用于后续请求(连接池)
pg:keepalive()
return res
end
return _M
##4.环境变量配置
创建.env文件:
PG_HOST=localhost
PG_PORT=5432
PG_DATABASE=mydatabase
PG_USER=myuser
PG_PASSWORD=mypassword123!
在Nginx配置中加载:
init_by_lua_block {
require"resty.core"
--从环境变量读取数据库配置,避免硬编码密码到代码中。
}
location/api/{
access_by_lua_file conf/db_auth.lua;--专门处理数据库认证逻辑的文件。
}
##5.常见错误及解决
| 错误信息 | 原因 | 解决方案 |
|---|---|---|
password authentication failed for user |
密码错误或用户不存在 | 检查用户名密码,确认PostgreSQL中用户存在 |
no pg_hba.conf entry for host |
IP不在白名单中 | 在pg_hba.conf中添加对应IP段的记录 |
connection refused |
PostgreSQL未启动或端口错误 | 检查服务状态和端口配置 |
FATAL: Peer authentication failed for user |
使用了peer认证 | 改为md5或password认证 |
##6.调试步骤
###测试连接:
psql-hlocalhost-Umyuser-dmydatabase-W#手动测试连接,输入密码确认可连通性。
\q退出psql shell后继续排查OpenResty端问题。
###查看详细日志:
在nginx.conf中添加调试日志:
location/test-db{
content_by_lua_block{
local pg=require"pgmoon".new({...})
ngx.log(ngx.DEBUG,"Connecting to:",cjson.encode(pg.config))
...
}
}
通过以上步骤应该能解决你的pgmoon认证问题!
内容由零声教学AI助手提供,问题来源于学员提问




