forked from baron/baron-sso
한 endpoint URL로 전체 서빙 #120
This commit is contained in:
@@ -1,34 +0,0 @@
|
||||
# ==========================================
|
||||
# Baron SSO - Unified Environment Configuration
|
||||
# ==========================================
|
||||
|
||||
# --- General System ---
|
||||
APP_ENV=development
|
||||
TZ=Asia/Seoul
|
||||
|
||||
# --- Infrastructure Ports ---
|
||||
DB_PORT=5432
|
||||
CLICKHOUSE_PORT_HTTP=8123
|
||||
CLICKHOUSE_PORT_NATIVE=9000
|
||||
BACKEND_PORT=3000
|
||||
USERFRONT_PORT=5000
|
||||
|
||||
# --- Database Credentials (PostgreSQL) ---
|
||||
DB_USER=baron
|
||||
DB_PASSWORD=password
|
||||
DB_NAME=baron_sso
|
||||
|
||||
# --- Backend Configuration ---
|
||||
# Must be 32 bytes. Generate with `openssl rand -hex 32`
|
||||
COOKIE_SECRET=super-secret-key-must-be-32-bytes!
|
||||
REDIS_ADDR=redis:6379
|
||||
|
||||
# --- Frontend Configuration ---
|
||||
# Descope Project ID (Required for Auth)
|
||||
DESCOPE_PROJECT_ID=P2t...your_descope_project_id
|
||||
|
||||
# --- Naver Cloud Services ---
|
||||
NAVER_CLOUD_ACCESS_KEY=ncp_iam_...
|
||||
NAVER_CLOUD_SECRET_KEY=ncp_iam_...
|
||||
NAVER_CLOUD_SERVICE_ID=ncp:sms:kr:...:...
|
||||
NAVER_SENDER_PHONE_NUMBER=...
|
||||
@@ -1,5 +1,6 @@
|
||||
# Stage 1: Build Flutter
|
||||
FROM ghcr.io/cirruslabs/flutter:stable AS build
|
||||
ENV RUN_FLUTTER_AS_ROOT=true
|
||||
# ENV RUN_FLUTTER_AS_ROOT=true
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:descope/descope.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import '../../../../core/services/auth_proxy_service.dart';
|
||||
import '../../../../core/services/auth_token_store.dart';
|
||||
|
||||
class ApproveQrScreen extends StatefulWidget {
|
||||
final String? pendingRef;
|
||||
@@ -19,8 +20,9 @@ class _ApproveQrScreenState extends State<ApproveQrScreen> {
|
||||
Future<void> _handleApprove() async {
|
||||
if (widget.pendingRef == null) return;
|
||||
|
||||
final storedToken = AuthTokenStore.getToken();
|
||||
final session = Descope.sessionManager.session;
|
||||
if (session == null || session.refreshToken.isExpired) {
|
||||
if (storedToken == null && (session == null || session.refreshToken.isExpired)) {
|
||||
setState(() => _message = "Please log in on your phone first.");
|
||||
context.go('/signin'); // Redirect to login
|
||||
return;
|
||||
@@ -32,9 +34,10 @@ class _ApproveQrScreenState extends State<ApproveQrScreen> {
|
||||
});
|
||||
// jwt 유효성 확인
|
||||
try {
|
||||
final token = storedToken ?? session?.sessionToken.jwt ?? '';
|
||||
await AuthProxyService.approveQrLogin(
|
||||
widget.pendingRef!,
|
||||
session.sessionToken.jwt,
|
||||
token,
|
||||
);
|
||||
setState(() {
|
||||
_success = true;
|
||||
|
||||
@@ -33,7 +33,6 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
|
||||
// QR Login Variables
|
||||
String? _qrImageBase64;
|
||||
String? _qrPendingRef;
|
||||
String? _qrUserCode;
|
||||
bool _isQrLoading = false;
|
||||
Timer? _qrPollingTimer;
|
||||
int _qrRemainingSeconds = 0;
|
||||
@@ -207,7 +206,6 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
|
||||
setState(() {
|
||||
_isQrLoading = true;
|
||||
_qrImageBase64 = null;
|
||||
_qrUserCode = null;
|
||||
_qrRemainingSeconds = 0;
|
||||
});
|
||||
|
||||
@@ -218,7 +216,6 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
|
||||
_qrImageBase64 = res['qrCode'];
|
||||
_qrPendingRef = res['pendingRef'];
|
||||
_qrRemainingSeconds = res['expiresIn'] ?? 300;
|
||||
_qrUserCode = res['userCode']?.toString();
|
||||
final interval = res['interval'];
|
||||
if (interval is int && interval > 0) {
|
||||
_qrPollIntervalMs = interval * 1000;
|
||||
@@ -992,7 +989,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
|
||||
codeOnly: true,
|
||||
);
|
||||
},
|
||||
child: const Text("코드만 받기(${_formatTime(_linkResendSeconds)})"),
|
||||
child: Text("코드만 받기(${_formatTime(_linkResendSeconds)})"),
|
||||
),
|
||||
],
|
||||
],
|
||||
@@ -1035,14 +1032,6 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
if (_qrUserCode != null) ...[
|
||||
Text(
|
||||
"코드: $_qrUserCode",
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
],
|
||||
const Text(
|
||||
"모바일 앱으로 스캔하세요",
|
||||
textAlign: TextAlign.center,
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:go_router/go_router.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:descope/descope.dart';
|
||||
import '../../../core/services/auth_proxy_service.dart';
|
||||
import '../../../core/services/auth_token_store.dart';
|
||||
|
||||
class QRScanScreen extends StatefulWidget {
|
||||
const QRScanScreen({super.key});
|
||||
@@ -49,7 +50,8 @@ class _QRScanScreenState extends State<QRScanScreen> {
|
||||
|
||||
_log.info('QR Code detected raw: $qrData, ref: $pendingRef');
|
||||
|
||||
final sessionToken = Descope.sessionManager.session?.sessionToken.jwt;
|
||||
final sessionToken = AuthTokenStore.getToken() ??
|
||||
Descope.sessionManager.session?.sessionToken.jwt;
|
||||
if (sessionToken == null) {
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
@@ -119,4 +121,4 @@ class _QRScanScreenState extends State<QRScanScreen> {
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ server {
|
||||
|
||||
access_log /var/log/nginx/access.log json_combined;
|
||||
|
||||
# Backend API Proxy
|
||||
# --- Backend API Proxy ---
|
||||
location /api {
|
||||
proxy_pass http://baron_backend:3000;
|
||||
proxy_set_header Host $host;
|
||||
@@ -34,7 +34,55 @@ server {
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
# Frontend Static Files
|
||||
# --- Ory Stack Proxy (via Oathkeeper) ---
|
||||
# Kratos Public API
|
||||
location /auth {
|
||||
proxy_pass http://oathkeeper:4455;
|
||||
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;
|
||||
}
|
||||
|
||||
# Hydra Public API
|
||||
location /oidc {
|
||||
proxy_pass http://oathkeeper:4455;
|
||||
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;
|
||||
}
|
||||
|
||||
# --- Internal Web Apps Proxy --- 초반에는 외부 오픈 없이 Private Net 내부에서만 운영
|
||||
# AdminFront (Vite Dev Server or Nginx)
|
||||
# location /admin {
|
||||
# proxy_pass http://baron_adminfront:5173;
|
||||
# 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;
|
||||
|
||||
# # WebSocket support (for Vite HMR)
|
||||
# proxy_http_version 1.1;
|
||||
# proxy_set_header Upgrade $http_upgrade;
|
||||
# proxy_set_header Connection "upgrade";
|
||||
# }
|
||||
|
||||
# # DevFront (Vite Dev Server or Nginx)
|
||||
# location /dev {
|
||||
# proxy_pass http://baron_devfront:5173;
|
||||
# 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;
|
||||
|
||||
# # WebSocket support (for Vite HMR)
|
||||
# proxy_http_version 1.1;
|
||||
# proxy_set_header Upgrade $http_upgrade;
|
||||
# proxy_set_header Connection "upgrade";
|
||||
# }
|
||||
|
||||
# --- UserFront Static Files ---
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
Reference in New Issue
Block a user