본문 바로가기

Stack/Lowcode

[Mendix] 메일 딥링크(DeepLink) + SAML SSO 구현 (자동메일링 바로가기 링크)

반응형
Mendix 실전 개발기

Mendix 메일 딥링크(DeepLink) + SAML SSO 구현
— 메일 버튼 클릭 한 번으로 팝업 페이지까지

자동발송 메일 본문에 "시스템 바로가기" 버튼을 넣고, 클릭 시 SAML SSO 로그인을 거쳐 Mendix 팝업 페이지로 바로 이동하는 전체 흐름을 단계별로 정리했습니다.

Mendix 10.x DeepLink 모듈 SAML SSO 메일 자동발송 사내 Mendix Cloud
0 문제 정의 — 왜 단순하지 않은가

Mendix는 기본적으로 SPA(Single Page Application) 구조라 URL이 하나입니다. 페이지 이동이 내부 상태로 처리되어, 외부에서 특정 팝업 페이지로 바로 들어오는 딥링크가 기본적으로 동작하지 않습니다. 여기에 회사 SAML SSO까지 끼면 아래 세 가지 문제가 겹칩니다.

문제 원인 해결 수단
외부 URL로 내부 페이지 접근 불가 SPA 구조, 단일 엔드포인트 DeepLink 모듈
로그인 전 딥링크 URL 소실 SSO 리디렉션 시 원래 URL 유실 Force login + LoginLocation 상수
SAML 로그인 후 원래 URL 복귀 cont 파라미터 전달 여부 js_SSOLogin 자동 실행
💡
Popup Layout ≠ 브라우저 팝업
Mendix에서 팝업처럼 보이는 화면은 레이아웃만 PopupLayout으로 설정된 일반 Page입니다. 진짜 별도 창이 아니기 때문에 DeepLink 모듈로 충분히 직접 연결할 수 있습니다.
1 전체 흐름 한눈에 보기
메일 바로가기 버튼 클릭 시 흐름
🔗 딥링크 접근 → SSO → 팝업 오픈
메일 버튼
클릭
/link/reviewmeeting/
토큰값
미로그인
감지
PG_Login
페이지
SAML SSO
로그인

복기회의록
팝업 오픈 ✅
MF_DeepLink
실행
딥링크 URL
복원
SSO
완료
* 이미 로그인된 상태면 PG_Login 없이 MF 직접 실행
복기회의록 등록 시 흐름 (메일 발송 측)
📧 복기회의록 등록 → 메일 발송
[등록] 버튼
클릭
IVK_ShowPage
_ReviewMeeting
Token 생성
+ HTML 삽입
복기회의록
팝업 오픈

[메일발송] 버튼
MF_SendMail
_Main
딥링크 버튼
포함 메일 발송 ✅
두 MF의 역할 구분
IVK_ShowPage_ReviewMeeting_NewEdit — 복기회의록 Object 생성 + Token 생성 + 딥링크 URL을 Details HTML에 삽입
MF_SendMail_Main — 이미 만들어진 Object를 메일로 발송 (이 MF는 수정 불필요)
2 Step 1 — ReviewMeeting 엔티티에 Token 추가

Mendix 내부 ID를 URL에 그대로 노출하면 보안상 좋지 않습니다. 별도 Token 어트리뷰트를 만들어 랜덤 값을 부여하고 딥링크 식별자로 사용합니다.

1
Domain Model 열기
MyApp 모듈 → ReviewMeeting 엔티티 더블클릭
2
Token 어트리뷰트 추가
New attribute → Name: Token / Type: String
3
IVK_ShowPage_ReviewMeeting_NewEdit에서 Token 세팅
Create ReviewMeeting 액션 더블클릭 → Token 어트리뷰트 값 설정
 
Mendix Expression — Token 생성
// 방법 1: round() 사용 (Mendix 기본 함수)
toString(round(random() * 1000000000)) + toString(round(random() * 1000000000))

// 방법 2: CommunityCommons 모듈이 있다면
CommunityCommons.CreateGUID()

// 방법 3: java.util.UUID (Java Action 없이는 동작 안 할 수 있음)
java.util.UUID.randomUUID().toString()
⚠️
generateGUID()는 Mendix 10.x에서 없음
구버전 예제에서 자주 보이는 generateGUID()는 10.x에서 동작하지 않습니다. round()를 활용한 방법 1이 가장 안전합니다.
3 Step 2 — DeepLink 처리 Microflow 생성

딥링크 URL이 접근될 때 실행되는 MF입니다. Token으로 Object를 조회하고 페이지를 엽니다.

MF 기본 정보
항목
MF 이름 MF_DeepLink_OpenReviewMeeting
파라미터 이름 UrlPath
파라미터 타입 String
MF 내부 흐름
1
Retrieve ReviewMeeting
Source: From database / XPath Builder에서 Token = $UrlPath 조건 설정 / Range: First
2
Exclusive Split (분기)
조건: $ReviewMeeting != empty
false → 에러 페이지 또는 홈페이지 Show
true → 다음 단계
3
연관 Object들 Retrieve
팝업 페이지에 필요한 파라미터(ActionItem, ActionItemClear, ExternalInspectionIssue, UIContext_2)를 Association 또는 XPath로 조회합니다.
빠른 방법: 원래 등록 MF에서 Create 이후 Show Page까지 블록 복사(Ctrl+C) 후 붙여넣고 앞단 Create만 Retrieve로 교체
4
Show Page
Page: PG_ReviewMeeting_NewEdit (PopupLayout) / 파라미터로 조회한 Object들 전달
 
XPath — Token으로 ReviewMeeting 조회
[MyApp.ReviewMeeting/Token = $UrlPath]

-- Builder 모드에서 설정 시:
-- 왼쪽: Token
-- 가운데: =
-- 오른쪽: $UrlPath (파라미터 선택)
💡
XPath 창 텍스트 모드에서 Token을 인식 못 하면 Ctrl+S로 저장 후 Builder 모드에서 드롭다운으로 선택하세요.
4 Step 3 — DeepLink 등록 MF 생성

앱 시작 시 어떤 URL 패턴에 어떤 MF를 연결할지 등록하는 MF입니다. Mendix 10.x에서는 상수(constant) 대신 Set Deeplink 액션으로 직접 등록합니다.

MF 이름 액션 설정값
MF_Setup_DeepLinks 액션 타입 Set Deeplink With String Input Parameters
Microflow MF_DeepLink_OpenReviewMeeting
Force login true ← SSO 강제
Deep link name reviewmeeting
Keep as home deeplink false
Deep link name이 URL 경로가 됩니다
reviewmeeting으로 설정하면 접근 URL은 /link/reviewmeeting/토큰값 형태가 됩니다. 쿼리스트링(?id=) 방식이 아니라 path 방식으로 토큰이 UrlPath 파라미터에 자동 전달됩니다.

패턴을 확인하려면 DeepLink 모듈 → _Use me → Examples → SetupExampleDeeplinks를 참고하세요.

5 Step 4 — After Startup 래퍼 MF 구성

Mendix App Settings의 After Startup에는 MF를 하나만 등록할 수 있습니다. 기존에 SAML StartSSO가 등록되어 있으므로, 두 MF를 순서대로 호출하는 래퍼 MF를 만들어야 합니다.

 
MF_AfterStartup 내부 흐름
[시작]
  → Call Microflow: CustomSAML.StartSSO
  → Call Microflow: MF_Setup_DeepLinks
[끝 — Return type: Boolean / Value: true]

※ End Event 리턴 타입을 Boolean으로 설정하지 않으면 에러 발생
1
MF_AfterStartup 생성 후 두 MF 순서대로 연결
End Event → Return type: Boolean, Value: true
2
App Settings 교체
App → Settings → Runtime 탭 → After startup → MF_AfterStartup 선택
⚠️
After Startup MF는 앱 재시작 시에만 실행됩니다. 배포 후 DeepLink가 동작하지 않는다면 앱을 Stop → Start로 완전 재시작하세요.
6 Step 5 — 메일 본문에 딥링크 버튼 삽입

복기회의록 등록 MF(IVK_ShowPage_ReviewMeeting_NewEdit)에서 Token을 생성한 직후 딥링크 버튼 HTML을 Details에 이어붙입니다.

MF 수정 순서
1
Create ReviewMeeting — Token 포함해서 생성
Token 어트리뷰트 값: toString(round(random() * 1000000000)) + toString(round(random() * 1000000000))
2
Change Object — Details에 버튼 HTML 추가
Create 바로 뒤에 Change Object 액션 삽입, 아래 Expression 사용
3
이후 흐름 (ActionItem, UIContext 등) 은 기존 그대로 유지
메일 발송 MF(MF_SendMail_Main)는 수정 불필요
 
Mendix Expression — Change Object / Details
$NewReviewMeeting/Details +
'<br><br>' +
'<div style="text-align:center;margin-top:16px;">' +
'<a href="https://your-app.mendixcloud.com/link/reviewmeeting/' +
$NewReviewMeeting/Token +
'" style="display:inline-block;background-color:#1890ff;color:white;' +
'padding:10px 24px;text-decoration:none;border-radius:4px;font-size:14px;">' +
'🔗 시스템 바로가기' +
'</a>' +
'</div>'
⚠️
URL 하드코딩 이슈
DeepLink.SUB_GetApplicationURL MF가 도커 내부 호스트명을 반환하는 경우 운영 URL을 직접 하드코딩해야 합니다. 개발/운영 분기가 필요하다면 Mendix Constant를 환경별로 다르게 설정하는 방법을 사용하세요.
7 Step 6 — DeepLink 모듈 상수 설정 (SAML 연동)

딥링크 클릭 시 미로그인 상태면 어디로 보낼지, SSO 완료 후 어디로 돌아올지를 상수로 설정합니다.

상수명 설정값 역할
LoginLocation /p/PG_Login 미로그인 시 이동할 로그인 페이지
SSOHandlerLocation /SSO/ SSO 완료 후 딥링크 복원 경로
💡
상수 위치: DeepLink 모듈 → _Use me → Configuration → (상수 목록)
Mendix 10.x에서는 UseDeepLink 같은 별도 활성화 상수가 없으며, After Startup 등록만으로 활성화됩니다.
SAML + DeepLink 연동 핵심

커스텀 SAML 모듈의 js_SSOLogin JavaScript Action이 현재 URL을 cont 파라미터로 붙여서 /sso로 리디렉션하는 구조입니다.

 
JavaScript — js_SSOLogin 내부 로직
export async function js_SSOLogin() {
    let href = window.location.href;
    let origin = window.location.origin;
    let pathname = href.replace(origin, "");
    pathname = pathname.replace('/#', '/p');

    let cont = "";
    if (pathname && pathname !== '/') {
        cont = `?cont=${pathname}`;  // 현재 URL을 cont 파라미터로 전달
    }

    window.location.href = `/sso${cont}`;  // /sso?cont=/link/reviewmeeting/토큰
    return Promise.resolve();
}

딥링크 접근 → PG_Login 이동 → 사용자가 SSO 버튼 클릭 → /sso?cont=/link/reviewmeeting/토큰으로 이동 → SSO 완료 → /link/reviewmeeting/토큰으로 복귀 → MF 실행 → 팝업 오픈

자동 SSO 리디렉션 (선택적 개선)
PG_Login 페이지에 HTML Snippet 위젯을 추가하면 버튼 클릭 없이 자동으로 SSO 페이지로 이동시킬 수 있습니다. 단, Mendix 10.x에서는 On page load 이벤트가 없으므로 아래 방법을 사용합니다.
 
HTML Snippet — PG_Login 자동 SSO 리디렉션 (선택)
<script>
  setTimeout(function() {
    let href = window.location.href;
    let origin = window.location.origin;
    let pathname = href.replace(origin, "");
    pathname = pathname.replace('/#', '/p');
    let cont = "";
    if (pathname && pathname !== '/') {
      cont = "?cont=" + pathname;
    }
    window.location.href = "/sso" + cont;
  }, 500);
</script>
8 트러블슈팅 & 함정 모음
증상 원인 해결
login.html로 이동됨 LoginLocation 상수가 비어있음 LoginLocation = /p/PG_Login 설정
"Page not found" 후 홈으로 이동 DeepLink 등록 MF가 After Startup에서 미실행 앱 완전 재시작 (Stop → Start)
Token URL에 소수점 포함 (1234.56...) random() 결과가 float round()로 감싸기
docker_example.com으로 URL 생성됨 SUB_GetApplicationURL이 내부 호스트 반환 운영 URL 하드코딩 또는 Constant 사용
Undefined variable 'DeepLinkURL' 변수 선언 전에 HTML에서 참조 Create 액션 내 참조 제거 → Change Object로 분리
After startup MF boolean 에러 End Event 리턴 타입 미설정 End Event → Return type: Boolean, Value: true
XPath에서 Token 인식 안 됨 엔티티 저장 전 참조 Ctrl+S 저장 후 Builder 모드에서 드롭다운 선택
generateGUID() 함수 없음 에러 Mendix 10.x에서 제거된 함수 toString(round(random() * 1000000000)) 사용
9 최종 체크리스트

✅ 구현 완료 체크리스트

🗄️
엔티티
Token 어트리뷰트 추가
⚙️
처리 MF
MF_DeepLink_Open 생성
🔗
등록 MF
MF_Setup_DeepLinks 생성
🚀
After Startup
래퍼 MF로 교체
📧
메일 본문
버튼 HTML 삽입
🔐
SAML 상수
LoginLocation 설정
↩️
SSO 복귀
SSOHandlerLocation 설정
🧪
테스트
운영 배포 후 확인
🎯
테스트 순서
1. 운영 배포 완료 확인 (CICD → 자동 재시작)
2. 복기회의록 새로 등록 (기존 데이터는 Token이 없음)
3. [메일발송] 클릭 → 메일 수신 확인
4. "🔗 시스템 바로가기" 버튼 클릭
5. SSO 로그인 → 복기회의록 팝업 오픈 확인

Mendix 10.12.8 / DeepLink 모듈 10.0.10 기준 · 사내 Mendix Cloud 운영 환경

반응형