Conversation
✅ Deploy Preview for kcloud-platform-iot ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Reviewer's Guide实现了自定义的 Spring Security 登录流程,使用 Thymeleaf/Vue 登录页和按授权类型划分的验证码键/端点;更新了认证域行为以及验证码的 Redis key 使用方式;优化了安全配置和网关路由;改进前端登录体验(自动跳转、默认值、清空按钮、新验证码 API);并调整了文档和许可证配置。 用户名密码验证码生成与获取的时序图sequenceDiagram
actor Browser
participant ReactLoginPage as ReactLoginPage
participant Gateway as Gateway
participant AuthService as AuthService
participant CaptchasController as CaptchasController
participant CaptchasServiceI as CaptchasServiceI
participant CaptchaGetQryExe as CaptchaGetQryExe
participant RedisUtils as RedisUtils
Browser->>ReactLoginPage: Open SPA login page
ReactLoginPage->>ReactLoginPage: uuidV7()
ReactLoginPage->>Gateway: GET /apis/auth/api/v1/username-password/captchas/{uuid}
Gateway->>AuthService: GET /v1/username-password/captchas/{uuid}
AuthService->>CaptchasController: getUsernamePasswordAuthCaptchaByUuid(uuid)
CaptchasController->>CaptchasServiceI: getCaptchaByUuid(CaptchaGetQry(key))
CaptchasServiceI->>CaptchaGetQryExe: execute(CaptchaGetQry)
CaptchaGetQryExe->>CaptchaGetQryExe: generate Captcha
CaptchaGetQryExe->>RedisUtils: set(key,captcha,5min)
RedisUtils-->>CaptchaGetQryExe: ok
CaptchaGetQryExe-->>CaptchasServiceI: Result(base64)
CaptchasServiceI-->>CaptchasController: Result(base64)
CaptchasController-->>AuthService: Result(base64)
AuthService-->>Gateway: Result(base64)
Gateway-->>ReactLoginPage: Result(base64)
ReactLoginPage->>Browser: Render captcha image
Spring Security 自定义登录页流程的时序图sequenceDiagram
actor User
participant Browser
participant Gateway as Gateway
participant AuthService as AuthService
participant LoginController as LoginController
participant Thymeleaf as Thymeleaf
participant SpringSecurity as SpringSecurity
User->>Browser: Navigate to /login
Browser->>Gateway: GET /api/login
Gateway->>AuthService: GET /login
AuthService->>LoginController: login()
LoginController-->>Thymeleaf: View name login
Thymeleaf-->>AuthService: Render login.html
AuthService-->>Gateway: HTML login page
Gateway-->>Browser: HTML login page
User->>Browser: Fill form and submit
Browser->>Gateway: POST /api/login (form data)
Gateway->>AuthService: POST /login (form data)
AuthService->>SpringSecurity: UsernamePasswordAuthenticationFilter
SpringSecurity->>SpringSecurity: Authenticate
SpringSecurity-->>AuthService: Success or failure
AuthService-->>Gateway: Redirect to target or /login?error
Gateway-->>Browser: Redirect response
更新后的认证验证码与登录组件类图classDiagram
class AuthA {
<<final>>
-Long serialVersionUID
-IdGenerator authIdGenerator
-HttpRequest httpRequest
-PasswordValidator passwordValidator
-CaptchaValidator captchaValidator
-UserValidator userValidator
-GrantType grantType
-CaptchaV captchaV
-UserV userV
-SendCaptchaType sendCaptchaType
+AuthA(authIdGenerator,httpRequest,passwordValidator,captchaValidator,userValidator,mobileCaptchaParamValidator)
+AuthA createUsernamePasswordAuth()
+AuthA createMobileAuth()
+AuthA createMailAuth()
+AuthA createAuthorizationCodeAuth()
+AuthA createTestAuth()
+AuthA createCaptchaVBySend(uuid,tag,tenantCode)
-boolean isUseCaptcha()
-String getCaptchaCacheKeyByAuth()
-AuthA create()
}
class CaptchasController {
-CaptchasServiceI captchasServiceI
+Result getUsernamePasswordAuthCaptchaByUuid(uuid)
+Result getAuthorizationCodeAuthCaptchaByUuid(uuid)
}
class CaptchaGetQry {
-String key
+CaptchaGetQry(key)
+String getKey()
}
class CaptchaGetQryExe {
-RedisUtils redisUtils
+Result execute(CaptchaGetQry qry)
-Captcha generate()
}
class RedisKeyUtils {
+String getUsernamePasswordAuthCaptchaKey(uuid)
+String getAuthorizationCodeAuthCaptchaKey(uuid)
}
class LoginController {
+String login()
}
class I18nFilter {
<<final>>
+doFilterInternal(request,response,filterChain)
}
AuthA ..> IdGenerator
AuthA ..> HttpRequest
AuthA ..> PasswordValidator
AuthA ..> CaptchaValidator
AuthA ..> UserValidator
CaptchasController --> CaptchasServiceI
CaptchasServiceI --> CaptchaGetQryExe
CaptchaGetQryExe --> RedisUtils
CaptchasController ..> CaptchaGetQry
RedisKeyUtils ..> CaptchasController
LoginController <.. OAuth2ResourceServerConfig
文件级变更
Tips and commands与 Sourcery 交互
自定义你的使用体验访问你的 控制面板 以:
获取帮助Original review guide in EnglishReviewer's GuideImplements a customized Spring Security login flow with a Thymeleaf/Vue login page and per-grant-type captcha keys/endpoints, updates auth domain behavior and redis key usage for captchas, refines security configs and gateway routes, improves front-end login UX (auto-redirect, default values, clear buttons, new captcha API), and adjusts documentation and licensing. Sequence diagram for username-password captcha generation and retrievalsequenceDiagram
actor Browser
participant ReactLoginPage as ReactLoginPage
participant Gateway as Gateway
participant AuthService as AuthService
participant CaptchasController as CaptchasController
participant CaptchasServiceI as CaptchasServiceI
participant CaptchaGetQryExe as CaptchaGetQryExe
participant RedisUtils as RedisUtils
Browser->>ReactLoginPage: Open SPA login page
ReactLoginPage->>ReactLoginPage: uuidV7()
ReactLoginPage->>Gateway: GET /apis/auth/api/v1/username-password/captchas/{uuid}
Gateway->>AuthService: GET /v1/username-password/captchas/{uuid}
AuthService->>CaptchasController: getUsernamePasswordAuthCaptchaByUuid(uuid)
CaptchasController->>CaptchasServiceI: getCaptchaByUuid(CaptchaGetQry(key))
CaptchasServiceI->>CaptchaGetQryExe: execute(CaptchaGetQry)
CaptchaGetQryExe->>CaptchaGetQryExe: generate Captcha
CaptchaGetQryExe->>RedisUtils: set(key,captcha,5min)
RedisUtils-->>CaptchaGetQryExe: ok
CaptchaGetQryExe-->>CaptchasServiceI: Result(base64)
CaptchasServiceI-->>CaptchasController: Result(base64)
CaptchasController-->>AuthService: Result(base64)
AuthService-->>Gateway: Result(base64)
Gateway-->>ReactLoginPage: Result(base64)
ReactLoginPage->>Browser: Render captcha image
Sequence diagram for Spring Security custom login page flowsequenceDiagram
actor User
participant Browser
participant Gateway as Gateway
participant AuthService as AuthService
participant LoginController as LoginController
participant Thymeleaf as Thymeleaf
participant SpringSecurity as SpringSecurity
User->>Browser: Navigate to /login
Browser->>Gateway: GET /api/login
Gateway->>AuthService: GET /login
AuthService->>LoginController: login()
LoginController-->>Thymeleaf: View name login
Thymeleaf-->>AuthService: Render login.html
AuthService-->>Gateway: HTML login page
Gateway-->>Browser: HTML login page
User->>Browser: Fill form and submit
Browser->>Gateway: POST /api/login (form data)
Gateway->>AuthService: POST /login (form data)
AuthService->>SpringSecurity: UsernamePasswordAuthenticationFilter
SpringSecurity->>SpringSecurity: Authenticate
SpringSecurity-->>AuthService: Success or failure
AuthService-->>Gateway: Redirect to target or /login?error
Gateway-->>Browser: Redirect response
Class diagram for updated auth captcha and login componentsclassDiagram
class AuthA {
<<final>>
-Long serialVersionUID
-IdGenerator authIdGenerator
-HttpRequest httpRequest
-PasswordValidator passwordValidator
-CaptchaValidator captchaValidator
-UserValidator userValidator
-GrantType grantType
-CaptchaV captchaV
-UserV userV
-SendCaptchaType sendCaptchaType
+AuthA(authIdGenerator,httpRequest,passwordValidator,captchaValidator,userValidator,mobileCaptchaParamValidator)
+AuthA createUsernamePasswordAuth()
+AuthA createMobileAuth()
+AuthA createMailAuth()
+AuthA createAuthorizationCodeAuth()
+AuthA createTestAuth()
+AuthA createCaptchaVBySend(uuid,tag,tenantCode)
-boolean isUseCaptcha()
-String getCaptchaCacheKeyByAuth()
-AuthA create()
}
class CaptchasController {
-CaptchasServiceI captchasServiceI
+Result getUsernamePasswordAuthCaptchaByUuid(uuid)
+Result getAuthorizationCodeAuthCaptchaByUuid(uuid)
}
class CaptchaGetQry {
-String key
+CaptchaGetQry(key)
+String getKey()
}
class CaptchaGetQryExe {
-RedisUtils redisUtils
+Result execute(CaptchaGetQry qry)
-Captcha generate()
}
class RedisKeyUtils {
+String getUsernamePasswordAuthCaptchaKey(uuid)
+String getAuthorizationCodeAuthCaptchaKey(uuid)
}
class LoginController {
+String login()
}
class I18nFilter {
<<final>>
+doFilterInternal(request,response,filterChain)
}
AuthA ..> IdGenerator
AuthA ..> HttpRequest
AuthA ..> PasswordValidator
AuthA ..> CaptchaValidator
AuthA ..> UserValidator
CaptchasController --> CaptchasServiceI
CaptchasServiceI --> CaptchaGetQryExe
CaptchaGetQryExe --> RedisUtils
CaptchasController ..> CaptchaGetQry
RedisKeyUtils ..> CaptchasController
LoginController <.. OAuth2ResourceServerConfig
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (25)
WalkthroughThis PR implements dual licensing (Apache 2.0 and MIT), introduces authorization code OAuth2 grant type support with separate captcha endpoints, adds a Thymeleaf-based login page template with Vue3 frontend integration, refactors authentication domain logic, and enhances permission flags and frontend capabilities across the application. Changes
Sequence Diagram(s)sequenceDiagram
participant Client as Client/Browser
participant Controller as CaptchasController
participant RedisKeyUtils as RedisKeyUtils
participant Redis as Redis Cache
Client->>Controller: GET /v1/authorization-code/captchas/{uuid}
Controller->>RedisKeyUtils: getAuthorizationCodeAuthCaptchaKey(uuid)
RedisKeyUtils-->>Controller: "auth:authorization-code:captcha:{uuid}"
Controller->>Redis: GET auth:authorization-code:captcha:{uuid}
Redis-->>Controller: captcha data (or null)
Controller-->>Client: Result<String> with captcha
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
✨ Finishing Touches
🧪 Generate unit tests (beta)
📝 Coding Plan
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 OpenGrep (1.16.4)laokou-common/laokou-common-i18n/src/main/java/org/laokou/common/i18n/util/RedisKeyUtils.java┌──────────────┐ �[32m✔�[39m �[1mOpengrep OSS�[0m �[1m Loading rules from local config...�[0m laokou-common/laokou-common-security/src/main/java/org/laokou/common/security/config/OAuth2ResourceServerConfig.java┌──────────────┐ �[32m✔�[39m �[1mOpengrep OSS�[0m �[1m Loading rules from local config...�[0m laokou-common/laokou-common-security/src/main/java/org/laokou/common/security/filter/I18nFilter.java┌──────────────┐ �[32m✔�[39m �[1mOpengrep OSS�[0m �[1m Loading rules from local config...�[0m
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment Tip CodeRabbit can use TruffleHog to scan for secrets in your code with verification capabilities.Add a TruffleHog config file (e.g. trufflehog-config.yml, trufflehog.yml) to your project to customize detectors and scanning behavior. The tool runs only when a config file is present. |
Review Summary by QodoAdd authorization code auth, custom login page, and dual licensing
WalkthroughsDescription• Add authorization code authentication with dedicated captcha endpoint • Implement custom login page with Thymeleaf and Vue3 UI • Refactor captcha endpoints to support multiple auth types • Update dual licensing to Apache 2.0 and MIT • Add default credentials and improve login form UX Diagramflowchart LR
A["Auth System"] -->|"Add captcha key"| B["RedisKeyUtils"]
A -->|"New endpoint"| C["Authorization Code Captcha"]
A -->|"Refactor"| D["Username/Password Captcha"]
E["LoginController"] -->|"Render"| F["login.html Template"]
F -->|"Vue3 + Element Plus"| G["Custom Login UI"]
H["Licensing"] -->|"Add MIT"| I["Dual License"]
I -->|"Keep Apache 2.0"| J["License Files"]
File Changes1. laokou-common/laokou-common-i18n/src/main/java/org/laokou/common/i18n/util/RedisKeyUtils.java
|
Code Review by Qodo
1. Auth-code captcha null
|
There was a problem hiding this comment.
Hey - 我发现了两个问题,并给出了一些总体反馈:
- 在 React 登录页中,
tenant_code、username和password的硬编码initialValue默认值(laokouyun/admin/admin123)在演示环境里很方便,但在生产环境存在安全风险;建议只在开发环境通过配置开关启用,或在非开发构建中移除这些默认值。 - 在 README.md 中,修改后的
<img>标签的height属性无效(height=(免费用于毕设、二开、商用、二次开源)400),会导致 HTML 解析出错;应当改回纯数字值,或把这段文字移到正文中。
给 AI Agent 的提示
Please address the comments from this code review:
## Overall Comments
- On the React login page, the hardcoded `initialValue` defaults for `tenant_code`, `username`, and `password` (`laokouyun` / `admin` / `admin123`) are convenient for demos but risky for production; consider gating them behind a development flag or removing them for non-dev builds.
- In README.md, the modified `<img>` tag has an invalid `height` attribute (`height=(免费用于毕设、二开、商用、二次开源)400`), which will break HTML parsing; this should be corrected to a numeric value or moved into the text.
## Individual Comments
### Comment 1
<location path="laokou-service/laokou-auth/laokou-auth-start/src/main/resources/templates/login.html" line_range="10-19" />
<code_context>
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/element-plus@2.7.8/dist/index.css"/>
</code_context>
<issue_to_address>
**🚨 suggestion (security):** Relying on unauthenticated CDN assets (Vue/Element Plus) on the login page can introduce availability and supply-chain risks.
Here you’re loading Element Plus from jsDelivr without Subresource Integrity or a local fallback. For an auth entrypoint, this increases exposure to CDN compromise/MITM and outages.
Prefer either:
- Self‑hosting a pinned version of this asset, or
- Adding `integrity` + `crossorigin` attributes and a local fallback.
This better controls the login surface and reduces dependency on third‑party infrastructure.
Suggested implementation:
```
<!-- Element Plus(Vue3 UI)
使用带 SRI 的 CDN + 本地回退,降低供应链与可用性风险 -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/element-plus@2.7.8/dist/index.css"
integrity="<!-- TODO: replace with real SRI hash for element-plus@2.7.8/dist/index.css -->"
crossorigin="anonymous"
referrerpolicy="no-referrer"
/>
<!-- 本地回退,当 CDN 不可用或被阻断时生效 -->
<link
rel="stylesheet"
th:href="@{/static/element-plus/2.7.8/dist/index.css}"
href="/static/element-plus/2.7.8/dist/index.css"
/>
```
1. 将 `element-plus@2.7.8/dist/index.css` 下载到项目静态目录(示例为 `src/main/resources/static/element-plus/2.7.8/dist/index.css`)或根据你们现有静态资源路径调整 `th:href`/`href`。
2. 使用官方工具或本地计算生成该 CSS 文件的真实 SRI 值(例如:`openssl dgst -sha256 -binary index.css | openssl base64 -A`,然后拼成 `sha256-...`)并替换占位的 `integrity` 内容。
3. 如项目的静态资源路径不以 `/static` 开头,请同步更新 `th:href` 与 `href` 中的 URL 以符合现有约定。
</issue_to_address>
### Comment 2
<location path="README.md" line_range="66" />
<code_context>
- 适用于中大型微服务IoT项目【业务复杂】
-<img src="doc/image/img_1.png" width=400 height=400 alt="COLA架构图"/>
+<img src="doc/image/img_1.png" width=400 height=(免费用于毕设、二开、商用、二次开源)400 alt="COLA架构图"/>
<img src="doc/image/img.png" width=400 height=400 alt="COLA架构图"/>
</code_context>
<issue_to_address>
**issue (bug_risk):** Image `height` attribute appears corrupted and will likely break HTML rendering.
The `height` value currently contains the text `(免费用于毕设、二开、商用、二次开源)`, which makes the attribute invalid and prevents the height from being applied. Please change it back to a plain numeric value (e.g., `height=400`).
</issue_to_address>帮我变得更有用!请对每条评论点 👍 或 👎,我会根据你的反馈改进后续 Review。
Original comment in English
Hey - I've found 2 issues, and left some high level feedback:
- On the React login page, the hardcoded
initialValuedefaults fortenant_code,username, andpassword(laokouyun/admin/admin123) are convenient for demos but risky for production; consider gating them behind a development flag or removing them for non-dev builds. - In README.md, the modified
<img>tag has an invalidheightattribute (height=(免费用于毕设、二开、商用、二次开源)400), which will break HTML parsing; this should be corrected to a numeric value or moved into the text.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- On the React login page, the hardcoded `initialValue` defaults for `tenant_code`, `username`, and `password` (`laokouyun` / `admin` / `admin123`) are convenient for demos but risky for production; consider gating them behind a development flag or removing them for non-dev builds.
- In README.md, the modified `<img>` tag has an invalid `height` attribute (`height=(免费用于毕设、二开、商用、二次开源)400`), which will break HTML parsing; this should be corrected to a numeric value or moved into the text.
## Individual Comments
### Comment 1
<location path="laokou-service/laokou-auth/laokou-auth-start/src/main/resources/templates/login.html" line_range="10-19" />
<code_context>
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/element-plus@2.7.8/dist/index.css"/>
</code_context>
<issue_to_address>
**🚨 suggestion (security):** Relying on unauthenticated CDN assets (Vue/Element Plus) on the login page can introduce availability and supply-chain risks.
Here you’re loading Element Plus from jsDelivr without Subresource Integrity or a local fallback. For an auth entrypoint, this increases exposure to CDN compromise/MITM and outages.
Prefer either:
- Self‑hosting a pinned version of this asset, or
- Adding `integrity` + `crossorigin` attributes and a local fallback.
This better controls the login surface and reduces dependency on third‑party infrastructure.
Suggested implementation:
```
<!-- Element Plus(Vue3 UI)
使用带 SRI 的 CDN + 本地回退,降低供应链与可用性风险 -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/element-plus@2.7.8/dist/index.css"
integrity="<!-- TODO: replace with real SRI hash for element-plus@2.7.8/dist/index.css -->"
crossorigin="anonymous"
referrerpolicy="no-referrer"
/>
<!-- 本地回退,当 CDN 不可用或被阻断时生效 -->
<link
rel="stylesheet"
th:href="@{/static/element-plus/2.7.8/dist/index.css}"
href="/static/element-plus/2.7.8/dist/index.css"
/>
```
1. 将 `element-plus@2.7.8/dist/index.css` 下载到项目静态目录(示例为 `src/main/resources/static/element-plus/2.7.8/dist/index.css`)或根据你们现有静态资源路径调整 `th:href`/`href`。
2. 使用官方工具或本地计算生成该 CSS 文件的真实 SRI 值(例如:`openssl dgst -sha256 -binary index.css | openssl base64 -A`,然后拼成 `sha256-...`)并替换占位的 `integrity` 内容。
3. 如项目的静态资源路径不以 `/static` 开头,请同步更新 `th:href` 与 `href` 中的 URL 以符合现有约定。
</issue_to_address>
### Comment 2
<location path="README.md" line_range="66" />
<code_context>
- 适用于中大型微服务IoT项目【业务复杂】
-<img src="doc/image/img_1.png" width=400 height=400 alt="COLA架构图"/>
+<img src="doc/image/img_1.png" width=400 height=(免费用于毕设、二开、商用、二次开源)400 alt="COLA架构图"/>
<img src="doc/image/img.png" width=400 height=400 alt="COLA架构图"/>
</code_context>
<issue_to_address>
**issue (bug_risk):** Image `height` attribute appears corrupted and will likely break HTML rendering.
The `height` value currently contains the text `(免费用于毕设、二开、商用、二次开源)`, which makes the attribute invalid and prevents the height from being applied. Please change it back to a plain numeric value (e.g., `height=400`).
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/element-plus@2.7.8/dist/index.css"/> | ||
|
|
||
| <style> | ||
| :root{ | ||
| --brand: #1677ff; | ||
| --bg1: #0b1220; | ||
| --bg2: #0e1a2b; | ||
| --card: rgba(255,255,255,.92); | ||
| --cardBorder: rgba(255,255,255,.35); | ||
| --text: rgba(0,0,0,.88); |
There was a problem hiding this comment.
🚨 suggestion (security): 在登录页依赖未经验证的 CDN 资源(Vue / Element Plus),会带来可用性和供应链方面的风险。
当前你是从 jsDelivr 加载 Element Plus,但没有使用子资源完整性(Subresource Integrity,SRI),也没有本地回退方案。对于认证入口页面来说,这会增加在 CDN 被攻破、中间人攻击(MITM)以及 CDN 宕机时的风险暴露面。
建议改为:
- 自行托管一份固定版本的静态资源,或
- 在使用 CDN 时增加
integrity+crossorigin属性,并提供本地回退资源。
这样可以更好地控制登录入口的安全面,并降低对第三方基础设施的依赖。
建议的实现方式:
<!-- Element Plus(Vue3 UI)
使用带 SRI 的 CDN + 本地回退,降低供应链与可用性风险 -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/element-plus@2.7.8/dist/index.css"
integrity="<!-- TODO: replace with real SRI hash for element-plus@2.7.8/dist/index.css -->"
crossorigin="anonymous"
referrerpolicy="no-referrer"
/>
<!-- 本地回退,当 CDN 不可用或被阻断时生效 -->
<link
rel="stylesheet"
th:href="@{/static/element-plus/2.7.8/dist/index.css}"
href="/static/element-plus/2.7.8/dist/index.css"
/>
- 将
element-plus@2.7.8/dist/index.css下载到项目静态目录(示例为src/main/resources/static/element-plus/2.7.8/dist/index.css)或根据你们现有静态资源路径调整th:href/href。 - 使用官方工具或本地计算生成该 CSS 文件的真实 SRI 值(例如:
openssl dgst -sha256 -binary index.css | openssl base64 -A,然后拼成sha256-...)并替换占位的integrity内容。 - 如项目的静态资源路径不以
/static开头,请同步更新th:href与href中的 URL 以符合现有约定。
Original comment in English
🚨 suggestion (security): Relying on unauthenticated CDN assets (Vue/Element Plus) on the login page can introduce availability and supply-chain risks.
Here you’re loading Element Plus from jsDelivr without Subresource Integrity or a local fallback. For an auth entrypoint, this increases exposure to CDN compromise/MITM and outages.
Prefer either:
- Self‑hosting a pinned version of this asset, or
- Adding
integrity+crossoriginattributes and a local fallback.
This better controls the login surface and reduces dependency on third‑party infrastructure.
Suggested implementation:
<!-- Element Plus(Vue3 UI)
使用带 SRI 的 CDN + 本地回退,降低供应链与可用性风险 -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/element-plus@2.7.8/dist/index.css"
integrity="<!-- TODO: replace with real SRI hash for element-plus@2.7.8/dist/index.css -->"
crossorigin="anonymous"
referrerpolicy="no-referrer"
/>
<!-- 本地回退,当 CDN 不可用或被阻断时生效 -->
<link
rel="stylesheet"
th:href="@{/static/element-plus/2.7.8/dist/index.css}"
href="/static/element-plus/2.7.8/dist/index.css"
/>
- 将
element-plus@2.7.8/dist/index.css下载到项目静态目录(示例为src/main/resources/static/element-plus/2.7.8/dist/index.css)或根据你们现有静态资源路径调整th:href/href。 - 使用官方工具或本地计算生成该 CSS 文件的真实 SRI 值(例如:
openssl dgst -sha256 -binary index.css | openssl base64 -A,然后拼成sha256-...)并替换占位的integrity内容。 - 如项目的静态资源路径不以
/static开头,请同步更新th:href与href中的 URL 以符合现有约定。
| - 适用于中大型微服务IoT项目【业务复杂】 | ||
|
|
||
| <img src="doc/image/img_1.png" width=400 height=400 alt="COLA架构图"/> | ||
| <img src="doc/image/img_1.png" width=400 height=(免费用于毕设、二开、商用、二次开源)400 alt="COLA架构图"/> |
There was a problem hiding this comment.
issue (bug_risk): 图片的 height 属性似乎已被破坏,很可能会导致 HTML 渲染异常。
当前 height 的值包含文本 (免费用于毕设、二开、商用、二次开源),这会使该属性变成无效值,导致高度设置无法生效。请将其改回纯数字值(例如 height=400)。
Original comment in English
issue (bug_risk): Image height attribute appears corrupted and will likely break HTML rendering.
The height value currently contains the text (免费用于毕设、二开、商用、二次开源), which makes the attribute invalid and prevents the height from being applied. Please change it back to a plain numeric value (e.g., height=400).
| return List.of(GrantType.USERNAME_PASSWORD, GrantType.MOBILE, GrantType.MAIL, GrantType.AUTHORIZATION_CODE) | ||
| .contains(grantType); | ||
| } | ||
|
|
||
| private boolean isUsePassword() { |
There was a problem hiding this comment.
1. Auth-code captcha null 🐞 Bug ✓ Correctness
AuthA now requires captcha for AUTHORIZATION_CODE but createAuthorizationCodeAuth() never initializes captchaV, so DomainService.auth() will hit a NullPointerException in checkCaptcha() when captchaV is dereferenced.
Agent Prompt
## Issue description
AUTHORIZATION_CODE auth now goes through captcha validation, but `AuthA.createAuthorizationCodeAuth()` never sets `captchaV`. This makes `AuthA.checkCaptcha()` dereference `captchaV` and crash with a NullPointerException.
## Issue Context
- `DomainService.auth()` always invokes `authA.checkCaptcha()`.
- `isUseCaptcha()` includes `GrantType.AUTHORIZATION_CODE`.
- `checkCaptcha()` reads `this.captchaV.captcha()` and `getCaptchaCacheKeyByAuth()` reads `this.captchaV.uuid()`.
## Fix Focus Areas
- laokou-service/laokou-auth/laokou-auth-domain/src/main/java/org/laokou/auth/model/AuthA.java[220-224]
- laokou-service/laokou-auth/laokou-auth-domain/src/main/java/org/laokou/auth/model/AuthA.java[323-333]
- laokou-service/laokou-auth/laokou-auth-domain/src/main/java/org/laokou/auth/model/AuthA.java[383-400]
- laokou-service/laokou-auth/laokou-auth-app/src/main/java/org/laokou/auth/service/validator/AuthorizationCodeAuthParamValidator.java[37-47]
## Suggested approach
1. Add a method like `getCaptchaVByAuthorizationCodeAuth()` (similar to username-password) that reads `uuid` and `captcha` parameters.
2. In `createAuthorizationCodeAuth()`, set `this.captchaV = getCaptchaVByAuthorizationCodeAuth()`.
3. Update `AuthorizationCodeAuthParamValidator` to validate the captcha-related parameters if captcha is required for this grant type.
4. Alternatively (if captcha is not intended for AUTHORIZATION_CODE), remove it from `isUseCaptcha()` and from `getCaptchaCacheKeyByAuth()`.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| - /api/v1/username-password/captchas/{uuid}=laokou-gateway | ||
| - /api/v1/authorization-code/captchas/{uuid}=laokou-gateway | ||
| - /api/v1/secrets=laokou-gateway | ||
| - /doc.html=laokou-gateway | ||
| - /webjars/**=laokou-gateway | ||
| - /ws=laokou-gateway | ||
| - /api/login=laokou-gateway |
There was a problem hiding this comment.
2. Gateway login path mismatch 🐞 Bug ⛯ Reliability
Gateway unauthenticated allowlist includes GET /api/login but the auth server exposes the login page at /login, so accessing /login through the gateway will not match the allowlist and will be blocked by AuthFilter as Unauthorized.
Agent Prompt
## Issue description
Gateway allowlist permits `GET /api/login`, but the auth service login page is `GET /login` and Spring Security processes `POST /login`. Gateway `AuthFilter` blocks any request not in the allowlist when no Authorization header is present, making the login page unreachable through the gateway.
## Issue Context
- Gateway relies on `request-matcher.ignore-patterns` to bypass auth.
- Auth service uses `/login` for login page and login processing.
## Fix Focus Areas
- laokou-cloud/laokou-gateway/src/main/resources/application.yml[190-206]
- laokou-service/laokou-auth/laokou-auth-adapter/src/main/java/org/laokou/auth/web/LoginController.java[29-32]
- laokou-service/laokou-auth/laokou-auth-infrastructure/src/main/java/org/laokou/auth/config/OAuth2ResourceServerConfig.java[67-71]
## Suggested approach
1. Add `GET /login=laokou-gateway` and `POST /login=laokou-gateway` to the gateway ignore-patterns.
2. Remove or repurpose `/api/login` unless a real route exists.
3. If the intended public endpoint is `/api/login`, change the auth controller + Spring Security loginPage/loginProcessingUrl to `/api/login` and ensure templates resolve correctly.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| - /v1/username-password/captchas/{uuid}=laokou-auth | ||
| - /v1/authorization-code/captchas/{uuid}=laokou-auth | ||
| - /v1/secrets=laokou-auth | ||
| - /doc.html=laokou-auth | ||
| - /webjars/**=laokou-auth | ||
| - /login=laokou-auth |
There was a problem hiding this comment.
3. Standalone captcha whitelist stale 🐞 Bug ⛯ Reliability
Standalone auth resource-server ignore-patterns still whitelist only /v1/captchas/{uuid}, so the new
captcha endpoints won’t be publicly accessible in standalone mode and login flows that need captcha
will be blocked.
Agent Prompt
## Issue description
Standalone auth configuration still whitelists the removed captcha endpoint `/v1/captchas/{uuid}` and does not whitelist the new captcha endpoints. This blocks captcha retrieval pre-auth in standalone deployments.
## Issue Context
Auth service has migrated to:
- `/v1/username-password/captchas/{uuid}`
- `/v1/authorization-code/captchas/{uuid}`
## Fix Focus Areas
- laokou-service/laokou-standalone/laokou-standalone-auth/laokou-standalone-auth-start/src/main/resources/application.yml[150-160]
- laokou-service/laokou-auth/laokou-auth-start/src/main/resources/application.yml[160-165]
## Suggested approach
1. Replace `/v1/captchas/{uuid}` with the two new endpoints in standalone ignore-patterns.
2. Add `/login` to standalone ignore-patterns if the standalone auth deployment serves the Thymeleaf login page.
3. Keep the existing send-mail/send-mobile POST allowlist as-is.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| initialValue={'laokouyun'} | ||
| fieldProps={{ | ||
| size: 'large', | ||
| prefix: <TeamOutlined className={'prefixIcon'} />, | ||
| autoComplete: 'new-password', | ||
| }} | ||
| allowClear={true} | ||
| placeholder={t('login.tenantCode.placeholder')} | ||
| rules={[ | ||
| { |
There was a problem hiding this comment.
4. Hardcoded login defaults 🐞 Bug ⛨ Security
UI login form now hardcodes initial tenant_code, username, and password values (laokouyun/admin/admin123), which risks accidental use of default credentials and exposes them in UI by default.
Agent Prompt
## Issue description
The login form ships with hardcoded default values for tenant, username, and password. This can lead to insecure deployments and accidental credential exposure.
## Issue Context
These values are rendered on the client for every user visiting the login page.
## Fix Focus Areas
- ui/src/pages/Login/index.tsx[364-416]
## Suggested approach
1. Remove `initialValue` for `tenant_code`, `username`, `password`.
2. If demo defaults are desired, guard them with an explicit dev-only build-time flag (e.g., `process.env.NODE_ENV === 'development'`) and ensure production builds do not include them.
3. Add a test/lint rule to prevent committing plaintext password defaults.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|




Summary by Sourcery
引入带有验证码支持的自定义 Spring Security 登录页面,优化针对不同授权类型的认证验证码处理逻辑,并更新 UI/README 细节以匹配新的认证与许可模型。
新特性:
LoginController和 Spring Security 表单登录配置提供支持。缺陷修复:
增强改进:
final,并增强 ID 生成器的空安全性。构建:
文档:
Original summary in English
Summary by Sourcery
Introduce a custom Spring Security login page with captcha support, refine authentication captcha handling for different grant types, and update UI/README details to match the new auth and licensing model.
New Features:
Bug Fixes:
Enhancements:
Build:
Documentation:
Summary by CodeRabbit
New Features
Documentation
Chores