You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多独立URL Shiny应用实现单次跨应用统一登录方案咨询

多独立URL Shiny应用单点登录解决方案

1. 共享加密Cookie实现跨应用免登

核心思路:首个应用登录后生成加密认证Cookie,所有Shiny应用共用同一密钥验证Cookie有效性,合法则允许访问。

  • 操作步骤:
    1. 给所有应用配置相同的SECRET_KEY,用于加密/解密Cookie
    2. 登录应用中,验证身份后设置跨域名Cookie:
      library(shiny)
      library(digest)
      
      SECRET_KEY <- "你的共享密钥,注意保密!"
      
      ui <- fluidPage(
        textInput("username", "用户名"),
        passwordInput("password", "密码"),
        actionButton("login", "登录")
      )
      
      server <- function(input, output, session) {
        observeEvent(input$login, {
          # 替换为你的真实身份验证逻辑(如数据库校验)
          if(input$username == "admin" && input$password == "123456") {
            # 生成带时间戳的加密令牌,防止重复使用
            auth_token <- digest(paste(input$username, Sys.time(), SECRET_KEY), algo = "sha256")
            # 通知前端设置跨域Cookie
            session$sendCustomMessage("setCookie", list(
              name = "shiny_auth_token",
              value = auth_token,
              domain = ".yourdomain.com", # 替换为你的根域名(如.example.com)
              path = "/"
            ))
            # 登录成功跳转至目标应用
            updateQueryString("https://app2.yourdomain.com", mode = "replace")
          }
        })
      }
      
      # 新增JS处理Cookie设置,确保跨域生效
      ui <- tagList(
        ui,
        tags$script(HTML('
          Shiny.addCustomMessageHandler("setCookie", function(message) {
            document.cookie = `${message.name}=${message.value}; domain=${message.domain}; path=${message.path}; secure; SameSite=Lax`;
          });
        '))
      )
      
      shinyApp(ui, server)
      
    3. 其他应用启动时读取并验证Cookie:
      library(shiny)
      library(digest)
      
      SECRET_KEY <- "与登录应用完全一致的密钥"
      
      # 验证Cookie有效性的函数(可扩展过期时间校验)
      validate_auth <- function(cookie_value) {
        if(is.null(cookie_value)) return(FALSE)
        # 简化校验:实际场景可解析令牌中的用户信息与过期时间
        TRUE
      }
      
      ui <- fluidPage(
        h1("已登录应用2"),
        textOutput("welcome_msg")
      )
      
      server <- function(input, output, session) {
        # 从请求头提取Cookie
        auth_cookie <- session$request$HTTP_COOKIE
        auth_token <- NULL
        if(!is.null(auth_cookie)) {
          auth_token <- sub(".*shiny_auth_token=([^;]+).*", "\\1", auth_cookie)
        }
        
        # 验证失败则跳转回登录页
        if(is.null(auth_token) || !validate_auth(auth_token)) {
          updateQueryString("https://login.yourdomain.com", mode = "replace")
          return()
        }
        
        # 验证通过,正常运行应用逻辑
        output$welcome_msg <- renderText("欢迎回来,已通过身份认证!")
      }
      
      shinyApp(ui, server)
      
    注意:所有应用必须部署在同一根域名下(如app1.yourdomain.com、app2.yourdomain.com),且需开启HTTPS以保证Cookie安全与跨域有效性。

2. 反向代理统一认证(Nginx示例)

核心思路:用Nginx作为所有Shiny应用的入口,所有请求先经过Nginx的认证检查,通过后再转发至对应应用,无需修改应用代码。

  • 操作步骤:
    1. 配置Nginx,使用auth_request模块将所有请求导向登录应用做认证
    2. Nginx配置示例:
      server {
        listen 443 ssl;
        server_name *.yourdomain.com;
        ssl_certificate /证书路径/cert.pem;
        ssl_certificate_key /密钥路径/key.pem;
        
        # 所有请求先经过认证服务校验
        auth_request /auth;
        
        # 转发app1至对应Shiny端口
        location /app1 {
          proxy_pass http://localhost:3838/app1;
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
        }
        
        # 转发app2至对应Shiny端口
        location /app2 {
          proxy_pass http://localhost:3838/app2;
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
        }
        
        # 指向登录应用,用于身份校验
        location = /auth {
          proxy_pass http://localhost:3838/login;
          proxy_pass_request_body off;
          proxy_set_header Content-Length "";
          proxy_set_header X-Original-URI $request_uri;
        }
      }
      
    3. 登录应用需返回200 OK表示认证通过,返回401 Unauthorized表示未登录,Nginx会自动跳转至登录页面。

3. 商业版Shiny服务内置SSO

若使用Shiny Server Pro或Posit Connect,可直接利用其原生单点登录功能:

  • 进入后台Authentication设置,选择SAML或OAuth2协议,配置身份提供商(如Okta、Azure AD)
  • 所有部署的应用自动继承认证配置,用户一次登录即可访问全部应用

内容的提问来源于stack exchange,提问作者Keivan.k

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 08:04:42