@lobehub/lobehub 2.0.13 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -0
- package/changelog/v2.json +18 -0
- package/docker-compose/deploy/.env.example +35 -0
- package/docker-compose/deploy/.env.zh-CN.example +31 -0
- package/docker-compose/deploy/bucket.config.json +18 -0
- package/docker-compose/deploy/docker-compose.yml +148 -0
- package/docker-compose/deploy/searxng-settings.yml +2582 -0
- package/docker-compose/setup.sh +37 -88
- package/docs/self-hosting/advanced/auth/providers/casdoor.mdx +110 -0
- package/docs/self-hosting/advanced/auth/providers/casdoor.zh-CN.mdx +165 -0
- package/docs/self-hosting/platform/docker-compose.mdx +43 -561
- package/docs/self-hosting/platform/docker-compose.zh-CN.mdx +40 -537
- package/locales/en-US/setting.json +16 -0
- package/locales/zh-CN/setting.json +16 -0
- package/package.json +1 -1
- package/packages/const/src/url.ts +1 -1
- package/src/app/[variants]/(main)/agent/_layout/Sidebar/Cron/index.tsx +4 -2
- package/src/app/[variants]/(main)/agent/cron/[cronId]/features/CronJobContentEditor.tsx +39 -44
- package/src/app/[variants]/(main)/agent/cron/[cronId]/features/CronJobHeader.tsx +27 -20
- package/src/app/[variants]/(main)/agent/cron/[cronId]/features/CronJobSaveButton.tsx +4 -2
- package/src/app/[variants]/(main)/agent/cron/[cronId]/features/CronJobScheduleConfig.tsx +183 -145
- package/src/app/[variants]/(main)/agent/profile/features/AgentCronJobs/hooks/useAgentCronJobs.ts +3 -4
- package/src/app/[variants]/(main)/agent/profile/features/AgentCronJobs/index.tsx +4 -3
- package/src/app/[variants]/(main)/agent/profile/features/ProfileEditor/index.tsx +4 -3
- package/src/features/Conversation/Messages/AssistantGroup/components/MessageContent.tsx +6 -1
- package/src/locales/default/setting.ts +16 -0
- package/src/store/agent/slices/cron/action.ts +6 -4
package/docker-compose/setup.sh
CHANGED
|
@@ -263,10 +263,10 @@ show_message() {
|
|
|
263
263
|
tips_allow_ports)
|
|
264
264
|
case $LANGUAGE in
|
|
265
265
|
zh_CN)
|
|
266
|
-
echo "请确保服务器以下端口未被占用且能被访问:3210, 9000, 9001
|
|
266
|
+
echo "请确保服务器以下端口未被占用且能被访问:3210, 9000, 9001"
|
|
267
267
|
;;
|
|
268
268
|
*)
|
|
269
|
-
echo "Please make sure the following ports on the server are not occupied and can be accessed: 3210, 9000, 9001
|
|
269
|
+
echo "Please make sure the following ports on the server are not occupied and can be accessed: 3210, 9000, 9001"
|
|
270
270
|
;;
|
|
271
271
|
esac
|
|
272
272
|
;;
|
|
@@ -315,12 +315,10 @@ show_message() {
|
|
|
315
315
|
tips_init_database_failed)
|
|
316
316
|
case $LANGUAGE in
|
|
317
317
|
zh_CN)
|
|
318
|
-
echo "
|
|
319
|
-
echo "echo '{}' > init_data.json"
|
|
318
|
+
echo "无法初始化数据库"
|
|
320
319
|
;;
|
|
321
320
|
*)
|
|
322
|
-
echo "Failed to initialize the database.
|
|
323
|
-
echo "echo '{}' > init_data.json"
|
|
321
|
+
echo "Failed to initialize the database."
|
|
324
322
|
;;
|
|
325
323
|
esac
|
|
326
324
|
;;
|
|
@@ -338,7 +336,7 @@ show_message() {
|
|
|
338
336
|
case $LANGUAGE in
|
|
339
337
|
zh_CN)
|
|
340
338
|
echo "请选择部署模式:"
|
|
341
|
-
echo "(0) 域名模式(访问时无需指明端口),需要使用反向代理服务 LobeHub, RustFS
|
|
339
|
+
echo "(0) 域名模式(访问时无需指明端口),需要使用反向代理服务 LobeHub, RustFS,并分别分配一个域名;"
|
|
342
340
|
echo "(1) 端口模式(访问时需要指明端口,如使用IP访问,或域名+端口访问),需要放开指定端口;"
|
|
343
341
|
echo "(2) 本地模式(仅供本地测试使用)"
|
|
344
342
|
echo "如果你对这些内容疑惑,可以先选择使用本地模式进行部署,稍后根据文档指引再进行修改。"
|
|
@@ -346,7 +344,7 @@ show_message() {
|
|
|
346
344
|
;;
|
|
347
345
|
*)
|
|
348
346
|
echo "Please select the deployment mode:"
|
|
349
|
-
echo "(0) Domain mode (no need to specify the port when accessing), you need to use the reverse proxy service LobeHub, RustFS,
|
|
347
|
+
echo "(0) Domain mode (no need to specify the port when accessing), you need to use the reverse proxy service LobeHub, RustFS, and assign a domain name respectively;"
|
|
350
348
|
echo "(1) Port mode (need to specify the port when accessing, such as using IP access, or domain name + port access), you need to open the specified port;"
|
|
351
349
|
echo "(2) Local mode (for local testing only)"
|
|
352
350
|
echo "If you are confused about these contents, you can choose to deploy in local mode first, and then modify according to the document guide later."
|
|
@@ -408,31 +406,33 @@ download_file() {
|
|
|
408
406
|
}
|
|
409
407
|
|
|
410
408
|
print_centered() {
|
|
411
|
-
# Define colors
|
|
412
|
-
declare -A colors
|
|
413
|
-
colors=(
|
|
414
|
-
[black]="\e[30m"
|
|
415
|
-
[red]="\e[31m"
|
|
416
|
-
[green]="\e[32m"
|
|
417
|
-
[yellow]="\e[33m"
|
|
418
|
-
[blue]="\e[34m"
|
|
419
|
-
[magenta]="\e[35m"
|
|
420
|
-
[cyan]="\e[36m"
|
|
421
|
-
[white]="\e[37m"
|
|
422
|
-
[reset]="\e[0m"
|
|
423
|
-
)
|
|
424
409
|
local text="$1" # Get input texts
|
|
425
410
|
local color="${2:-reset}" # Get color, default to reset
|
|
426
411
|
local term_width=$(tput cols) # Get terminal width
|
|
427
412
|
local text_length=${#text} # Get text length
|
|
428
413
|
local padding=$(((term_width - text_length) / 2)) # Get padding
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
414
|
+
|
|
415
|
+
# Get color code (compatible with bash 3.x)
|
|
416
|
+
local color_code=""
|
|
417
|
+
local reset_code="\e[0m"
|
|
418
|
+
case "$color" in
|
|
419
|
+
black) color_code="\e[30m" ;;
|
|
420
|
+
red) color_code="\e[31m" ;;
|
|
421
|
+
green) color_code="\e[32m" ;;
|
|
422
|
+
yellow) color_code="\e[33m" ;;
|
|
423
|
+
blue) color_code="\e[34m" ;;
|
|
424
|
+
magenta) color_code="\e[35m" ;;
|
|
425
|
+
cyan) color_code="\e[36m" ;;
|
|
426
|
+
white) color_code="\e[37m" ;;
|
|
427
|
+
reset) color_code="\e[0m" ;;
|
|
428
|
+
*)
|
|
429
|
+
echo "Invalid color specified. Available colors: black red green yellow blue magenta cyan white reset"
|
|
430
|
+
return 1
|
|
431
|
+
;;
|
|
432
|
+
esac
|
|
433
|
+
|
|
434
434
|
# Print the text with padding
|
|
435
|
-
printf "%*s${
|
|
435
|
+
printf "%*s${color_code}%s${reset_code}\n" $padding "" "$text"
|
|
436
436
|
}
|
|
437
437
|
|
|
438
438
|
# Usage:
|
|
@@ -469,10 +469,9 @@ ask() {
|
|
|
469
469
|
# == Variables ==
|
|
470
470
|
# ===============
|
|
471
471
|
# File list
|
|
472
|
-
SUB_DIR="docker-compose/
|
|
472
|
+
SUB_DIR="docker-compose/deploy"
|
|
473
473
|
FILES=(
|
|
474
474
|
"$SUB_DIR/docker-compose.yml"
|
|
475
|
-
"$SUB_DIR/init_data.json"
|
|
476
475
|
"$SUB_DIR/searxng-settings.yml"
|
|
477
476
|
"$SUB_DIR/bucket.config.json"
|
|
478
477
|
)
|
|
@@ -481,10 +480,7 @@ ENV_EXAMPLES=(
|
|
|
481
480
|
"$SUB_DIR/.env.example"
|
|
482
481
|
)
|
|
483
482
|
# Default values
|
|
484
|
-
CASDOOR_PASSWORD="pswd123"
|
|
485
|
-
CASDOOR_SECRET="CASDOOR_SECRET"
|
|
486
483
|
RUSTFS_SECRET_KEY="YOUR_RUSTFS_PASSWORD"
|
|
487
|
-
CASDOOR_HOST="localhost:8000"
|
|
488
484
|
RUSTFS_HOST="localhost:9000"
|
|
489
485
|
PROTOCOL="http"
|
|
490
486
|
|
|
@@ -514,9 +510,8 @@ section_download_files(){
|
|
|
514
510
|
fi
|
|
515
511
|
|
|
516
512
|
download_file "$SOURCE_URL/${FILES[0]}" "docker-compose.yml"
|
|
517
|
-
download_file "$SOURCE_URL/${FILES[1]}" "
|
|
518
|
-
download_file "$SOURCE_URL/${FILES[2]}" "
|
|
519
|
-
download_file "$SOURCE_URL/${FILES[3]}" "bucket.config.json"
|
|
513
|
+
download_file "$SOURCE_URL/${FILES[1]}" "searxng-settings.yml"
|
|
514
|
+
download_file "$SOURCE_URL/${FILES[2]}" "bucket.config.json"
|
|
520
515
|
# Download .env.example with the specified language
|
|
521
516
|
if [ "$LANGUAGE" = "zh_CN" ]; then
|
|
522
517
|
download_file "$SOURCE_URL/${ENV_EXAMPLES[0]}" ".env"
|
|
@@ -576,15 +571,10 @@ section_configurate_host() {
|
|
|
576
571
|
echo "LobeHub" $(show_message "ask_domain" "example.com")
|
|
577
572
|
ask "(example.com)"
|
|
578
573
|
LOBE_HOST="$ask_result"
|
|
579
|
-
# If user use domain mode, ask for the domain of RustFS
|
|
574
|
+
# If user use domain mode, ask for the domain of RustFS
|
|
580
575
|
echo "RustFS S3 API" $(show_message "ask_domain" "s3.example.com")
|
|
581
576
|
ask "(s3.example.com)"
|
|
582
577
|
RUSTFS_HOST="$ask_result"
|
|
583
|
-
echo "Casdoor API" $(show_message "ask_domain" "auth.example.com")
|
|
584
|
-
ask "(auth.example.com)"
|
|
585
|
-
CASDOOR_HOST="$ask_result"
|
|
586
|
-
# Setup callback url for Casdoor
|
|
587
|
-
sed "${SED_INPLACE_ARGS[@]}" "s/"example.com"/${LOBE_HOST}/" init_data.json
|
|
588
578
|
;;
|
|
589
579
|
1)
|
|
590
580
|
DEPLOY_MODE="ip"
|
|
@@ -595,21 +585,15 @@ section_configurate_host() {
|
|
|
595
585
|
# If user use ip mode, append the port to the host
|
|
596
586
|
LOBE_HOST="${HOST}:3210"
|
|
597
587
|
RUSTFS_HOST="${HOST}:9000"
|
|
598
|
-
CASDOOR_HOST="${HOST}:8000"
|
|
599
|
-
# Setup callback url for Casdoor
|
|
600
|
-
sed "${SED_INPLACE_ARGS[@]}" "s/"localhost:3210"/${LOBE_HOST}/" init_data.json
|
|
601
588
|
;;
|
|
602
589
|
*)
|
|
603
590
|
echo "Invalid deploy mode: $ask_result"
|
|
604
591
|
exit 1
|
|
605
592
|
;;
|
|
606
593
|
esac
|
|
607
|
-
|
|
594
|
+
|
|
608
595
|
# lobe host
|
|
609
596
|
sed "${SED_INPLACE_ARGS[@]}" "s#^APP_URL=.*#APP_URL=$PROTOCOL://$LOBE_HOST#" .env
|
|
610
|
-
# auth related
|
|
611
|
-
sed "${SED_INPLACE_ARGS[@]}" "s#^AUTH_CASDOOR_ISSUER=.*#AUTH_CASDOOR_ISSUER=$PROTOCOL://$CASDOOR_HOST#" .env
|
|
612
|
-
sed "${SED_INPLACE_ARGS[@]}" "s#^origin=.*#origin=$PROTOCOL://$CASDOOR_HOST#" .env
|
|
613
597
|
# s3 related
|
|
614
598
|
sed "${SED_INPLACE_ARGS[@]}" "s#^S3_PUBLIC_DOMAIN=.*#S3_PUBLIC_DOMAIN=$PROTOCOL://$RUSTFS_HOST#" .env
|
|
615
599
|
sed "${SED_INPLACE_ARGS[@]}" "s#^S3_ENDPOINT=.*#S3_ENDPOINT=$PROTOCOL://$RUSTFS_HOST#" .env
|
|
@@ -664,37 +648,7 @@ section_regenerate_secrets() {
|
|
|
664
648
|
exit 1
|
|
665
649
|
fi
|
|
666
650
|
echo $(show_message "security_secrect_regenerate")
|
|
667
|
-
|
|
668
|
-
# Generate CASDOOR_SECRET
|
|
669
|
-
CASDOOR_SECRET=$(generate_key 32)
|
|
670
|
-
if [ $? -ne 0 ]; then
|
|
671
|
-
echo $(show_message "security_secrect_regenerate_failed") "CASDOOR_SECRET"
|
|
672
|
-
else
|
|
673
|
-
# Search and replace the value of CASDOOR_SECRET in .env
|
|
674
|
-
sed "${SED_INPLACE_ARGS[@]}" "s#^AUTH_CASDOOR_SECRET=.*#AUTH_CASDOOR_SECRET=${CASDOOR_SECRET}#" .env
|
|
675
|
-
if [ $? -ne 0 ]; then
|
|
676
|
-
echo $(show_message "security_secrect_regenerate_failed") "AUTH_CASDOOR_SECRET in \`.env\`"
|
|
677
|
-
fi
|
|
678
|
-
# replace `clientSecrect` in init_data.json
|
|
679
|
-
sed "${SED_INPLACE_ARGS[@]}" "s#dbf205949d704de81b0b5b3603174e23fbecc354#${CASDOOR_SECRET}#" init_data.json
|
|
680
|
-
if [ $? -ne 0 ]; then
|
|
681
|
-
echo $(show_message "security_secrect_regenerate_failed") "AUTH_CASDOOR_SECRET in \`init_data.json\`"
|
|
682
|
-
fi
|
|
683
|
-
fi
|
|
684
|
-
|
|
685
|
-
# Generate Casdoor User
|
|
686
|
-
CASDOOR_USER="admin"
|
|
687
|
-
CASDOOR_PASSWORD=$(generate_key 10)
|
|
688
|
-
if [ $? -ne 0 ]; then
|
|
689
|
-
echo $(show_message "security_secrect_regenerate_failed") "CASDOOR_PASSWORD"
|
|
690
|
-
CASDOOR_PASSWORD="pswd123"
|
|
691
|
-
else
|
|
692
|
-
# replace `password` in init_data.json
|
|
693
|
-
sed "${SED_INPLACE_ARGS[@]}" "s/"pswd123"/${CASDOOR_PASSWORD}/" init_data.json
|
|
694
|
-
if [ $? -ne 0 ]; then
|
|
695
|
-
echo $(show_message "security_secrect_regenerate_failed") "CASDOOR_PASSWORD in \`init_data.json\`"
|
|
696
|
-
fi
|
|
697
|
-
fi
|
|
651
|
+
|
|
698
652
|
# Generate RUSTFS S3 User Password
|
|
699
653
|
RUSTFS_SECRET_KEY=$(generate_key 8)
|
|
700
654
|
if [ $? -ne 0 ]; then
|
|
@@ -735,13 +689,10 @@ section_init_database() {
|
|
|
735
689
|
fi
|
|
736
690
|
|
|
737
691
|
docker compose pull
|
|
738
|
-
docker compose up --detach postgresql
|
|
692
|
+
docker compose up --detach postgresql
|
|
739
693
|
# hopefully enough time for even the slower systems
|
|
740
694
|
sleep 15
|
|
741
695
|
docker compose stop
|
|
742
|
-
|
|
743
|
-
# Init finished, remove init mount
|
|
744
|
-
echo '{}' > init_data.json
|
|
745
696
|
}
|
|
746
697
|
|
|
747
698
|
show_message "ask_init_database"
|
|
@@ -759,16 +710,14 @@ fi
|
|
|
759
710
|
section_display_configurated_report() {
|
|
760
711
|
# Display configuration reports
|
|
761
712
|
echo $(show_message "security_secrect_regenerate_report")
|
|
762
|
-
|
|
763
|
-
echo -e "LobeHub: \n - URL: $PROTOCOL://$LOBE_HOST
|
|
764
|
-
echo -e "Casdoor: \n - URL: $PROTOCOL://$CASDOOR_HOST \n - Username: admin \n - Password: ${CASDOOR_PASSWORD}\n"
|
|
713
|
+
|
|
714
|
+
echo -e "LobeHub: \n - URL: $PROTOCOL://$LOBE_HOST"
|
|
765
715
|
echo -e "RustFS: \n - URL: $PROTOCOL://$RUSTFS_HOST \n - Username: admin\n - Password: ${RUSTFS_SECRET_KEY}\n"
|
|
766
|
-
|
|
716
|
+
|
|
767
717
|
# if user run in domain mode, diplay reverse proxy configuration
|
|
768
718
|
if [[ "$DEPLOY_MODE" == "domain" ]]; then
|
|
769
719
|
echo $(show_message "tips_add_reverse_proxy")
|
|
770
720
|
printf "\n%s\t->\t%s\n" "$LOBE_HOST" "127.0.0.1:3210"
|
|
771
|
-
printf "%s\t->\t%s\n" "$CASDOOR_HOST" "127.0.0.1:8000"
|
|
772
721
|
printf "%s\t->\t%s\n" "$RUSTFS_HOST" "127.0.0.1:9000"
|
|
773
722
|
fi
|
|
774
723
|
|
|
@@ -81,6 +81,116 @@ tags:
|
|
|
81
81
|
After successful deployment, users will be able to authenticate with Casdoor and use LobeChat.
|
|
82
82
|
</Callout>
|
|
83
83
|
|
|
84
|
+
## Docker Compose Deployment with Casdoor
|
|
85
|
+
|
|
86
|
+
If you're deploying LobeHub using Docker Compose, refer to the following configuration to integrate Casdoor as an authentication service.
|
|
87
|
+
|
|
88
|
+
### Reverse Proxy Configuration
|
|
89
|
+
|
|
90
|
+
In domain mode, you need to configure a reverse proxy to ensure Casdoor is accessible:
|
|
91
|
+
|
|
92
|
+
| Domain | Proxy Port | Description |
|
|
93
|
+
| ------------------ | ---------- | --------------- |
|
|
94
|
+
| `auth.example.com` | `8000` | Casdoor service |
|
|
95
|
+
|
|
96
|
+
<Callout type="important">
|
|
97
|
+
If you're using panel software like [aaPanel](https://www.bt.cn/) for reverse proxy configuration,
|
|
98
|
+
ensure it does not intercept requests to the `.well-known` path to facilitate the proper functioning of Casdoor's OAuth2 configuration.
|
|
99
|
+
Below is a whitelist configuration for the Nginx server block concerning paths for Casdoor reverse proxy:
|
|
100
|
+
|
|
101
|
+
```nginx
|
|
102
|
+
location /.well-known/openid-configuration {
|
|
103
|
+
proxy_pass http://localhost:8000; # Forward to localhost:8000
|
|
104
|
+
proxy_set_header Host $host; # Keep the original host header
|
|
105
|
+
proxy_set_header X-Real-IP $remote_addr; # Keep the client's real IP
|
|
106
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # Keep the forwarded IP
|
|
107
|
+
proxy_set_header X-Forwarded-Proto $scheme; # Keep the request protocol
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
⚠️ Please do not enable any form of caching in the reverse proxy settings of such panel software to avoid affecting the normal operation of the service.
|
|
112
|
+
See [https://github.com/lobehub/lobe-chat/discussions/5986](https://github.com/lobehub/lobe-chat/discussions/5986)
|
|
113
|
+
</Callout>
|
|
114
|
+
|
|
115
|
+
### Required Configuration
|
|
116
|
+
|
|
117
|
+
1. LobeHub needs to communicate with Casdoor, so you need to configure Casdoor's Issuer:
|
|
118
|
+
|
|
119
|
+
```env
|
|
120
|
+
AUTH_CASDOOR_ISSUER=https://auth.example.com
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
This configuration affects LobeHub's login authentication service. Ensure the Casdoor service URL is correct.
|
|
124
|
+
|
|
125
|
+
2. Allow callback URL in Casdoor to point to LobeHub:
|
|
126
|
+
|
|
127
|
+
In Casdoor's Web panel under `Authentication -> Applications` -> `<Application ID, default is app-built-in>` -> `Redirect URLs`, add:
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
https://lobe.example.com/api/auth/callback/casdoor
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
3. Casdoor needs Origin information in environment variables:
|
|
134
|
+
|
|
135
|
+
```env
|
|
136
|
+
origin=https://auth.example.com
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Troubleshooting
|
|
140
|
+
|
|
141
|
+
#### Cannot Login Properly
|
|
142
|
+
|
|
143
|
+
Check container logs for the following errors:
|
|
144
|
+
|
|
145
|
+
```sh
|
|
146
|
+
docker logs -f lobehub
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**r3: "response" is not a conform Authorization Server Metadata response**
|
|
150
|
+
|
|
151
|
+
```log
|
|
152
|
+
lobehub | [auth][error] r3: "response" is not a conform Authorization Server Metadata response (unexpected HTTP status code)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Cause: This issue is typically caused by improper reverse proxy configuration. Ensure your reverse proxy doesn't intercept Casdoor's OAuth2 configuration requests.
|
|
156
|
+
|
|
157
|
+
Solution:
|
|
158
|
+
|
|
159
|
+
- Refer to the reverse proxy configuration notes above.
|
|
160
|
+
|
|
161
|
+
- Direct troubleshooting: Access `https://auth.example.com/.well-known/openid-configuration`:
|
|
162
|
+
- If non-JSON data is returned, your reverse proxy configuration is incorrect.
|
|
163
|
+
- If the returned JSON's `"issuer": "URL"` field doesn't match `https://auth.example.com`, your environment variable configuration is incorrect.
|
|
164
|
+
|
|
165
|
+
**TypeError: fetch failed**
|
|
166
|
+
|
|
167
|
+
```log
|
|
168
|
+
lobehub | [auth][error] TypeError: fetch failed
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Cause: LobeHub cannot access the authentication service.
|
|
172
|
+
|
|
173
|
+
Solution:
|
|
174
|
+
|
|
175
|
+
- Check if your authentication service is running properly and if LobeHub's network can reach it.
|
|
176
|
+
|
|
177
|
+
- Direct troubleshooting: Use `curl` in the LobeHub container terminal to access `https://auth.example.com/.well-known/openid-configuration`. If JSON data is returned, your authentication service is working correctly.
|
|
178
|
+
|
|
179
|
+
#### OAuth Token Exchange Failures with Reverse Proxy
|
|
180
|
+
|
|
181
|
+
If OAuth authentication fails during the token exchange phase when using Docker behind a reverse proxy, this is typically caused by the default `MIDDLEWARE_REWRITE_THROUGH_LOCAL=1` setting.
|
|
182
|
+
|
|
183
|
+
**Solution**: Set `MIDDLEWARE_REWRITE_THROUGH_LOCAL=0` in your `.env` file and restart Docker containers:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
docker compose down
|
|
187
|
+
docker compose up -d
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Docker Compose Configuration Files
|
|
191
|
+
|
|
192
|
+
Casdoor Docker Compose configuration files can be found in the [docker-compose/local/casdoor](https://github.com/lobehub/lobe-chat/tree/main/docker-compose/local/casdoor) directory.
|
|
193
|
+
|
|
84
194
|
## Related Resources
|
|
85
195
|
|
|
86
196
|
- [Casdoor Documentation](https://casdoor.org/docs/overview)
|
|
@@ -77,6 +77,171 @@ tags:
|
|
|
77
77
|
|
|
78
78
|
<Callout type={'info'}>部署成功后,用户将可以通过 Casdoor 身份认证并使用 LobeChat。</Callout>
|
|
79
79
|
|
|
80
|
+
## Docker Compose 部署 Casdoor
|
|
81
|
+
|
|
82
|
+
如果你使用 Docker Compose 部署 LobeHub,可以参考以下配置来集成 Casdoor 作为鉴权服务。
|
|
83
|
+
|
|
84
|
+
### 反向代理配置
|
|
85
|
+
|
|
86
|
+
在域名模式中,你需要完成反向代理配置,并确保局域网 / 公网能访问到 Casdoor 服务:
|
|
87
|
+
|
|
88
|
+
| 域名 | 反代端口 | 说明 |
|
|
89
|
+
| ------------------ | ------ | ---------- |
|
|
90
|
+
| `auth.example.com` | `8000` | Casdoor 服务 |
|
|
91
|
+
|
|
92
|
+
<Callout type="important">
|
|
93
|
+
如果你使用如 [宝塔面板](https://www.bt.cn/) 等面板软件进行反向代理配置,
|
|
94
|
+
你需要确保其对 `.well-known` 路径的请求不进行拦截,以确保 Casdoor 的 OAuth2 配置能够正常工作。
|
|
95
|
+
这里提供一份针对 Casdoor 服务的 Nginx server 块的路径白名单配置:
|
|
96
|
+
|
|
97
|
+
```nginx
|
|
98
|
+
location /.well-known/openid-configuration {
|
|
99
|
+
proxy_pass http://localhost:8000; # 转发到 localhost:8000
|
|
100
|
+
proxy_set_header Host $host; # 保留原始主机头
|
|
101
|
+
proxy_set_header X-Real-IP $remote_addr; # 保留客户端真实IP
|
|
102
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 保留转发的IP
|
|
103
|
+
proxy_set_header X-Forwarded-Proto $scheme; # 保留请求协议
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
⚠️ 请不要在此类面板软件的反向代理设置中开启任何形式的缓存,以免影响服务的正常运行。
|
|
108
|
+
详情请见 [https://github.com/lobehub/lobe-chat/discussions/5986](https://github.com/lobehub/lobe-chat/discussions/5986)
|
|
109
|
+
</Callout>
|
|
110
|
+
|
|
111
|
+
### 必要配置
|
|
112
|
+
|
|
113
|
+
1. LobeHub 需要与 Casdoor 通讯,因此你需要配置 Casdoor 的 Issuer:
|
|
114
|
+
|
|
115
|
+
```env
|
|
116
|
+
AUTH_CASDOOR_ISSUER=https://auth.example.com
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
该配置会影响 LobeHub 的登录鉴权服务,你需要确保 Casdoor 服务的地址正确。
|
|
120
|
+
|
|
121
|
+
2. 在 Casdoor 中允许回调地址为 LobeHub 的地址:
|
|
122
|
+
|
|
123
|
+
请在 Casdoor 的 Web 面板的 `身份认证 -> 应用` -> `<应用ID,默认为 app-built-in>` -> `重定向URL` 中添加一行:
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
https://lobe.example.com/api/auth/callback/casdoor
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
3. Casdoor 需要在环境变量中提供访问的 Origin 信息:
|
|
130
|
+
|
|
131
|
+
```env
|
|
132
|
+
origin=https://auth.example.com
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### 使用 MinIO 存储 Casdoor 头像
|
|
136
|
+
|
|
137
|
+
允许用户在 Casdoor 中更换头像:
|
|
138
|
+
|
|
139
|
+
1. 你需要首先在 `buckets` 中创建一个名为 `casdoor` 的桶,选择自定义策略,复制并粘贴如下内容:
|
|
140
|
+
|
|
141
|
+
```json
|
|
142
|
+
{
|
|
143
|
+
"Statement": [
|
|
144
|
+
{
|
|
145
|
+
"Effect": "Allow",
|
|
146
|
+
"Principal": {
|
|
147
|
+
"AWS": ["*"]
|
|
148
|
+
},
|
|
149
|
+
"Action": ["s3:GetBucketLocation"],
|
|
150
|
+
"Resource": ["arn:aws:s3:::casdoor"]
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"Effect": "Allow",
|
|
154
|
+
"Principal": {
|
|
155
|
+
"AWS": ["*"]
|
|
156
|
+
},
|
|
157
|
+
"Action": ["s3:ListBucket"],
|
|
158
|
+
"Resource": ["arn:aws:s3:::casdoor"],
|
|
159
|
+
"Condition": {
|
|
160
|
+
"StringEquals": {
|
|
161
|
+
"s3:prefix": ["files/*"]
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"Effect": "Allow",
|
|
167
|
+
"Principal": {
|
|
168
|
+
"AWS": ["*"]
|
|
169
|
+
},
|
|
170
|
+
"Action": ["s3:PutObject", "s3:DeleteObject", "s3:GetObject"],
|
|
171
|
+
"Resource": ["arn:aws:s3:::casdoor/**"]
|
|
172
|
+
}
|
|
173
|
+
],
|
|
174
|
+
"Version": "2012-10-17"
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
2. 创建一个新的访问密钥,将生成的 `Access Key` 和 `Secret Key` 存储之
|
|
179
|
+
|
|
180
|
+
3. 在 Casdoor 的 `身份认证 -> 提供商` 中关联 MinIO S3 服务,以下是一个示例配置:
|
|
181
|
+
|
|
182
|
+

|
|
183
|
+
|
|
184
|
+
其中,客户端 ID、客户端密钥为上一步创建的访问密钥中的 `Access Key` 和 `Secret Key`,`192.168.31.251` 应当被替换为 `your_server_ip`。
|
|
185
|
+
|
|
186
|
+
4. 在 Casdoor 的 `身份认证 -> 应用` 中,对 `app-built-in` 应用添加提供商,选择 `minio`,保存并退出
|
|
187
|
+
|
|
188
|
+
5. 你可以在 Casdoor 的 `身份认证 -> 资源` 中,尝试上传文件以测试配置是否正确
|
|
189
|
+
|
|
190
|
+
### 常见问题
|
|
191
|
+
|
|
192
|
+
#### 无法正常登陆
|
|
193
|
+
|
|
194
|
+
请根据容器日志检查是否存在以下错误:
|
|
195
|
+
|
|
196
|
+
```sh
|
|
197
|
+
docker logs -f lobe-chat
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**r3: "response" is not a conform Authorization Server Metadata response**
|
|
201
|
+
|
|
202
|
+
```log
|
|
203
|
+
lobe-chat | [auth][error] r3: "response" is not a conform Authorization Server Metadata response (unexpected HTTP status code)
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
成因:该问题一般是由于你的反向代理配置不正确导致的,你需要确保你的反向代理配置不会拦截 Casdoor 的 OAuth2 配置请求。
|
|
207
|
+
|
|
208
|
+
解决方案:
|
|
209
|
+
|
|
210
|
+
- 请参考上方的反向代理配置注意事项。
|
|
211
|
+
|
|
212
|
+
- 一个直接的排查方式,你可以直接访问 `https://auth.example.com/.well-known/openid-configuration`,如果:
|
|
213
|
+
- 返回了非 JSON 格式的数据,则说明你的反向代理配置错误。
|
|
214
|
+
- 如果返回的 JSON 格式数据中的 `"issuer": "URL"` 字段不是你配置的 `https://auth.example.com`,则说明你的环境变量配置错误。
|
|
215
|
+
|
|
216
|
+
**TypeError: fetch failed**
|
|
217
|
+
|
|
218
|
+
```log
|
|
219
|
+
lobe-chat | [auth][error] TypeError: fetch failed
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
成因:LobeHub 无法访问鉴权服务。
|
|
223
|
+
|
|
224
|
+
解决方案:
|
|
225
|
+
|
|
226
|
+
- 请检查你的鉴权服务是否正常运行,以及 LobeHub 所在的网络是否能够访问到鉴权服务。
|
|
227
|
+
|
|
228
|
+
- 一个直接的排查方式,你可以在 LobeHub 容器的终端中,使用 `curl` 命令访问你的鉴权服务 `https://auth.example.com/.well-known/openid-configuration`,如果返回了 JSON 格式的数据,则说明你的鉴权服务正常运行。
|
|
229
|
+
|
|
230
|
+
#### 反向代理下 OAuth 令牌交换失败
|
|
231
|
+
|
|
232
|
+
如果在反向代理后使用 Docker 时 OAuth 认证在令牌交换阶段失败,这通常是由默认的 `MIDDLEWARE_REWRITE_THROUGH_LOCAL=1` 设置引起的,该设置会将 URL 重写为 `127.0.0.1:3210`。
|
|
233
|
+
|
|
234
|
+
**解决方案**: 在 `.env` 文件中设置 `MIDDLEWARE_REWRITE_THROUGH_LOCAL=0` 并重启 Docker 容器:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
docker compose down
|
|
238
|
+
docker compose up -d
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Docker Compose 配置文件
|
|
242
|
+
|
|
243
|
+
Casdoor 的 Docker Compose 配置文件可以在 [docker-compose/local/casdoor](https://github.com/lobehub/lobe-chat/tree/main/docker-compose/local/casdoor) 目录中找到。
|
|
244
|
+
|
|
80
245
|
## 相关资源
|
|
81
246
|
|
|
82
247
|
- [Casdoor 文档](https://casdoor.org/docs/overview)
|