当前位置: 首页 > wzjs >正文

河北做it的网站加快实施创新驱动发展战略

河北做it的网站,加快实施创新驱动发展战略,做家政的在哪些网站推广,做venn的网站这阵子不是deepseek火么?我也折腾了下本地部署,ollama、vllm、llama.cpp都弄了下,webui也用了几个,发现nextjs-ollama-llm-ui小巧方便,挺适合个人使用的。如果放在网上供多人使用的话,得接入登录认证才好&a…

这阵子不是deepseek火么?我也折腾了下本地部署,ollama、vllm、llama.cpp都弄了下,webui也用了几个,发现nextjs-ollama-llm-ui小巧方便,挺适合个人使用的。如果放在网上供多人使用的话,得接入登录认证才好,不然所有人都能蹭玩,这个可不太妙。
我是用openresty反向代理将webui发布出去的,有好几种方案实现接入外部登录认证系统。首先是直接修改nextjs-ollama-llm-ui的源码,其实我就是这么做的,因为这样接入能将登录用户信息带入应用,可以定制页面,将用户显示在页面里,体验会更好。其次openresty是支持auth_request的,你需要编码实现几个web接口就可以了,进行简单配置即可,这种方式也很灵活,逻辑你自行编码实现。还有一种就是在openresty里使用lua来对接外部认证系统,也就是本文要介绍的内容。
在折腾的过程中,开始是想利用一些现有的轮子,结果因为偷懒反而踩了不少坑。包括但不限于openssl、session,后来一想,其实也没有多难,手搓也不复杂。
首先是这样设计的,用户的标识信息写入cookie,比如用一个叫做SID的字段,其构成为时间戳+IP,aes加密后的字符串;当用户的IP发生变化或者其他客户端伪造cookie访问,openresty可以识别出来,归类到未认证用户,跳转到认证服务器(带上回调url)。

location / {access_by_lua_block {local cookies = ngx.var.http_Cookieif not cookies thenreturn ngx.redirect('https://sso.yourdomain.com/oauth2/authorize?redirect_uri=https://webapp.yourdomain.com/callback')endlocal my_cookie = ngx.re.match(cookies, "sid=([^;]+)")if not my_cookie thenreturn ngx.redirect('https://sso.yourdomain.com/oauth2/authorize?redirect_uri=https://webapp.yourdomain.com/callback')endlocal ckv=my_cookie[1]local myfunc = require "myfunc"local decrypted = myfunc.mydecode(ckv)local getip=string.sub(decrypted,12)if getip ~= myfunc.get_client_ip() thenreturn ngx.redirect('https://sso.yourdomain.com/oauth2/authorize?redirect_uri=https://webapp.yourdomain.com/callback')endmyfunc.redget(ckv,'https://sso.yourdomain.com/oauth2/authorize?redirect_uri=https://webapp.yourdomain.com/callback')}proxy_pass   http://127.0.0.1:3000;
}

用户认证信息是存放在后端redis中,key是SID,value是认证访问返回的包含用户信息的json对象转的字符串,在认证成功后写入。在cookie设置时设定有效时长,在redis添加记录时设置有效时长。

location /callback {content_by_lua_block {local http = require "resty.http"local httpc = http.new()local args = ngx.req.get_uri_args()local ticket = args.ticketlocal res, err = httpc:request_uri("https://sso.yourdomain.com/oauth2/queryticket/"..ticket, {method = "POST",ssl_verify = false,headers = {  ["Content-Type"] = "application/json" }  })if not res thenngx.status = ngx.HTTP_INTERNAL_SERVER_ERRORngx.say("Failed to request user info: ", err)return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)endlocal cjson = require "cjson"local ok, data = pcall(cjson.decode, res.body)if not ok thenngx.status = 500ngx.say("解析 JSON 失败: ", data)returnendlocal username = data.usernamelocal json_str = cjson.encode(data)local timestamp = os.time()local myfunc = require "myfunc"local clientip = myfunc.get_client_ip()local text = timestamp ..":"..clientiplocal my_value=myfunc.myencode(text)myfunc.redset(my_value, json_str)ngx.header["Set-Cookie"] = "sid=" .. my_value .. "; Path=/; Expires=" .. ngx.cookie_time(ngx.time() + 14400) .. "; HttpOnly"ngx.say("<html><head><meta charset=UTF-8 http-equiv=refresh content=3;url='http://webapp.yourdomain.com/'></head><body> 欢迎你 " .. username .. "</body></html>")}
}

另外可以考虑是否需要在用户注销时主动删除记录,在nginx.conf里添加logout路径,需要在相关页面中放进去才好工作,否则用户估计不会在浏览器中手工输入logout的url来注销的。下面的代码只是简单地从cookie中将sid字段置空,其实更完备的话,是先检核sid有效性,然后前端cookie和后端redis中都要做相关处理,从略了。

location /logout {content_by_lua_block {ngx.header["Set-Cookie"] = "sid=; Path=/; Expires=" .. ngx.cookie_time(ngx.time() - 3600) .. "; HttpOnly"ngx.say("已注销")}
}

定义了一些函数:

--myfunc.lua
local resty_string = require "resty.string"
local resty_aes = require "resty.aes"
local key = "1234567890123456"  -- 16 bytes key for AES-128
local iv = "1234567890123456"   -- 16 bytes IV for AES-128
local aes = resty_aes:new(key, nil, resty_aes.cipher(128, "cbc"), {iv=iv})local _M = {}function _M.get_client_ip()local headers = ngx.req.get_headers()local client_iplocal x_forwarded_for = headers["X-Forwarded-For"]if x_forwarded_for thenclient_ip = x_forwarded_for:match("([^,]+)")endif not client_ip thenclient_ip = headers["X-Real-IP"]endif not client_ip thenclient_ip = ngx.var.remote_addrendreturn client_ip
endfunction _M.myencode(text)local encrypted = aes:encrypt(text)local my_value=resty_string.to_hex(encrypted)return my_value
endfunction _M.mydecode(hex_str)if not hex_str or hex_str:len() % 2 ~= 0 thenreturn nil, "Invalid hex string: length must be even"endlocal bin_data = ""for i = 1, #hex_str, 2 dolocal byte_str = hex_str:sub(i, i + 1)local byte = tonumber(byte_str, 16)if not byte thenreturn nil, "Invalid hex character: " .. byte_strendbin_data = bin_data .. string.char(byte)endlocal decrypted = aes:decrypt(bin_data)return decrypted
endfunction _M.redset(key,value)local redis = require "resty.redis"local red = redis:new()red:set_timeouts(1000, 1000, 1000)local ok, err = red:connect("127.0.0.1", 6379)if not ok thenngx.say("Failed to connect to Redis: ", err)returnendok, err = red:set(key,value,"EX",14400)if not ok thenngx.say("Failed to set key: ", err)returnend
endfunction _M.redget(key,redurl)local redis = require "resty.redis"local red = redis:new()red:set_timeouts(1000, 1000, 1000)local ok, err = red:connect("127.0.0.1", 6379)if not ok thenngx.say("Failed to connect to Redis: ", err)returnendlocal userinfo, err = red:get(key)if not userinfo thenreturn ngx.redirect(redurl)end
endreturn _M

其实也有现成的oauth2的轮子,不过我们自己手写lua代码的话,可以更灵活的配置,对接一些非标准的web认证服务也可以的。

http://www.dtcms.com/wzjs/210493.html

相关文章:

  • 怎么做网络推广品牌哪家强北京网站seo公司
  • 网站中flash怎么做今日头条新闻
  • php网站的客服窗口怎么做的查关键词
  • 河东苏州网站建设刷关键词排名seo软件
  • 网站设计与制作培训学校选择宁波seo优化公司
  • 模板式网站建设怎样建立个人网站
  • 深圳政府网站建设开平网站设计
  • 做JAVA基础编程题什么网站好长春百度推广排名优化
  • 有没有一起做网站的百度权重什么意思
  • 网站建设的公司业务seo公司多少钱
  • 金山石化网站建设seo最好的工具
  • 情公司做的网站怎么在网上销售
  • 网站建设H5 源码求个网站
  • 专业的购物网站定制成都百度推广公司电话
  • 廊坊做网站优化的公司百度快照优化
  • 闵行营销型网站建设公司it培训机构靠谱吗
  • 网站建设措施无限制搜索引擎排名
  • 网站首页快照怎么做网络推广计划方案
  • 网站做优化好还是做推广好网站正能量免费推广软件
  • 上海设计院排名独立站优化
  • prizm viewer wordpressseo优化培训公司
  • 上海seo优化公司 kinglinkseo企业站收录
  • 给政府做网站的公司网络营销与管理专业是干什么的
  • 沈阳做网站企业大数据营销
  • 广东高端网站建设vi设计
  • 哪里有网站制作技术seo是对网站进行什么优化
  • 查网站的关键词排名吗网络销售入门基本知识
  • 乐清案例上传网站爱站网关键词怎么挖掘
  • 保定网站建设价格互联网广告代理
  • phpmysql网站开发视频电商运营工资一般多少钱一个月