Logo
“使用TinyAuth和Traefik实现简单的认证代理”的封面

使用TinyAuth和Traefik实现简单的认证代理

Avatar

Skyone

科技爱好者

你是否遇到过需要为不支持认证的服务添加认证的情况?TinyAuth 是一个轻量级的认证代理,可以帮助你为这些服务添加基本的认证。本文将介绍如何使用 TinyAuth 和 Traefik 实现简单的认证代理。

TinyAuth 支持包括 GitHub OAuth、简单密码认证在内的多种认证方式,这里我使用 Pocket ID 为例。

准备工作

在开始之前,请确保你已经正确配置了 Traefik,并且可以通过 Traefik 访问你的服务。如果你还没有配置 Traefik,可以参考 使用 Traefik 作为 Docker 的反向代理 进行配置。

此外,我这里使用 Pocket ID 作为认证方式,你可以自行选择其他认证方式,参考 TinyAuth 的文档

现在假设有一个 echo 服务,需要添加认证,其域名是 echo.skyone.dev,我们需要在 .skyone.dev 下的任意子域名上部署 TinyAuth(与 echo 服务的域名在同一个域下),这里我使用 auth.skyone.dev

在 Pocket ID 中注册应用

首先,你需要访问 Pocket ID 的管理面板,在 OIDC Clients 标签页中点击 Add OIDC Client。会出现一个新菜单,提示你提供一些信息。我们只需要设置其中的两个字段:

  1. Client ID: 这是你的应用的唯一标识符,可以随意设置。
  2. Redirect URI: 这是 TinyAuth 的回调地址,格式为 https://tinyauth.domain/api/oauth/callback/generic 。例如,我的回调地址是 https://auth.skyone.dev/api/oauth/callback/generic

创建 Pocket ID 应用

其他的选项都可以保持默认。创建完成后,你会得到一个 Client ID 和 Client Secret,这两个值稍后会用到。

创建 Pocket ID 应用成功

部署 TinyAuth

接下来,我们需要配置 TinyAuth。首先,创建一个名为 tinyauth 的 Docker Compose 文件,内容如下:

name: tinyauth

services:
  tinyauth:
    image: ghcr.io/steveiliop56/tinyauth:v3
    container_name: tinyauth
    restart: unless-stopped
    networks:
      - proxy
    env_file:
      - docker.env
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=proxy"
      - "traefik.http.routers.tinyauth.rule=Host(`tinyauth.skyone.dev`)"
      - "traefik.http.routers.tinyauth.entrypoints=websecure"
      - "traefik.http.routers.tinyauth.service=tinyauth"
      - "traefik.http.services.tinyauth.loadBalancer.server.port=3000"
      - "traefik.http.middlewares.tinyauth.forwardAuth.address=http://tinyauth:3000/api/auth/traefik"

networks:
  proxy:
    external: true

这里需要修改的部分是 tinyauth.skyone.dev,将其替换为你自己的域名。

这里 labels 的最后一行为 Traefik 指定了一个中间件 tinyauth,这个中间件会在请求到达 tinyauth 服务之前进行认证,http://tinyauth:3000 是 TinyAuth 在容器内部的地址。

接下来,创建一个名为 docker.env 的环境变量文件,内容如下:

# --- Required Environment Variables ---
TINY_AUTH_DOMAIN="tinyauth.example.com"
POCKET_ID_DOMAIN="pocket-id.example.com"

POCKET_ID_NAME="Pocket ID"
SECRET=some-random-32-chars-string
GENERIC_CLIENT_ID="your-pocket-id-client-id"
GENERIC_CLIENT_SECRET="your-pocket-id-client-secret"

# --- DO NOT EDIT BELOW THIS LINE ---
APP_URL="https://${TINY_AUTH_DOMAIN}"
GENERIC_AUTH_URL="https://${POCKET_ID_DOMAIN}/authorize"
GENERIC_TOKEN_URL="https://${POCKET_ID_DOMAIN}/api/oidc/token"
GENERIC_USER_URL="https://${POCKET_ID_DOMAIN}/api/oidc/userinfo"
GENERIC_SCOPES="openid email profile groups"
GENERIC_NAME="${POCKET_ID_NAME}"

注释已经写得很清楚了,这里需要修改的部分是:

  • TINY_AUTH_DOMAIN: TinyAuth 的域名。
  • POCKET_ID_DOMAIN: Pocket ID 的域名。
  • GENERIC_CLIENT_ID: 在 Pocket ID 创建应用时获得的 Client ID。
  • GENERIC_CLIENT_SECRET: 在 Pocket ID 创建应用时获得的 Client Secret。
  • POCKET_ID_NAME: Pocket ID 的名称,可以随意设置,不会影响功能。
  • SECRET: 使用 openssl rand -hex 16 生成一个随机字符串,用于加密和签名。

编辑好 docker.env 后,运行 docker compose up -d 即可启动。

为 echo 服务启用认证代理

接下来,我们需要为 echo 服务添加 Traefik 的 labels,以便使用 TinyAuth 进行认证。echo 服务的 Docker Compose 文件如下:

name: echo

services:
  echo:
    container_name: echo
    image: luotianyi/echo:latest
    restart: unless-stopped
    networks:
      - proxy
    labels:
      - "tinyauth.domain=echo.skyone.dev"
      - "traefik.enable=true"
      - "traefik.http.routers.echo.entrypoints=websecure"
      - "traefik.http.routers.echo.rule=Host(`echo.skyone.dev`)"
      - "traefik.http.routers.echo.service=echo"
      - "traefik.http.services.echo.loadbalancer.server.port=5000"
      - "traefik.http.routers.echo.middlewares=tinyauth"

networks:
  proxy:
    external: true

只需要注意两行:

  • tinyauth.domain=echo.skyone.host: 这里的域名需要与 echo 服务的域名一致。
  • traefik.http.routers.echo.middlewares=tinyauth: 这行表示使用 TinyAuth 进行认证,这个中间件来自 tinyauth 容器的 labels。

你可以将这两行添加到你的任意需要认证的服务中,不需要别的操作即可实现认证。

测试认证

现在,你可以访问 https://echo.skyone.dev,会被重定向到 TinyAuth 的登录页面。登录后,你将被重定向回 echo 服务。

登录页面

重定向到 Pocket ID

登录成功

重定向到 echo 服务

注意,这里 TinyAuth 生成的 Cookie 位于 .skyone.dev 域名下,这就是 TinyAuth 和 echo 服务需要在同一个域名下的原因。

TinyAuth 域名服务域名是否能共享 Cookie说明
auth.skyone.devecho.skyone.dev✅ 可以同属于 skyone.dev,Cookie 有效
auth.skyone.devgrafana.skyone.dev✅ 可以也在 skyone.dev 下,Cookie 有效
auth.skyone.devecho.other.skyone.dev✅ 可以虽然多一层子域,但仍在 skyone.dev 下,Cookie 有效
auth.skyone.devecho.other.dev❌ 不可以根域名不同(skyone.devother.dev
auth1.skyone.devauth2.skyone.dev✅ 可以都在 skyone.dev 下,Cookie 有效
auth.other.skyone.devecho.skyone.dev❌ 不可以.other.skyone.dev 不包括 echo.skyone.dev

权限管理

TinyAuth + Pocket ID 的组合可以实现简单的权限管理。你可以在 Pocket ID 的管理面板中为不同的用户分配不同的权限。

例如,我希望 echo 服务只能被 admin 组的用户访问,可以在 Pocket ID 的管理面板中创建一个 admin 组,并将用户添加到该组中。然后在 echo 服务的 labels 中添加以下行:

- "tinyauth.oauth.groups=admin"

完成,当用户访问 echo 服务时,TinyAuth 会检查用户是否属于 admin 组,如果不属于,则会被拒绝访问。

同样的,也可以通过用户的邮箱来限制访问,例如:

- "tinyauth.oauth.whitelist=user1@example.com,/@regex\\.com$/,user2@example.com"

可以看到,支持正则表达式(注意转义),还是很不错的。

通过这种方式,TinyAuth 不仅能提供统一的登录入口,还能与 Pocket ID 的用户和组管理结合,实现精细化的访问控制。

【完】

使用TinyAuth和Traefik实现简单的认证代理

https://blog.skyone.dev/2025/tinyauth-traefik/

本文作者

Skyone

发布于

2025年8月16日

许可协议

CC BY-NC-SA 4.0

转载或引用本文时请遵守许可协议,注明出处、不得用于商业用途!


隐私政策

Copyright © Skyone 2025