Mendix 메일 딥링크(DeepLink) + SAML SSO 구현
— 메일 버튼 클릭 한 번으로 팝업 페이지까지
자동발송 메일 본문에 "시스템 바로가기" 버튼을 넣고, 클릭 시 SAML SSO 로그인을 거쳐 Mendix 팝업 페이지로 바로 이동하는 전체 흐름을 단계별로 정리했습니다.
Mendix는 기본적으로 SPA(Single Page Application) 구조라 URL이 하나입니다. 페이지 이동이 내부 상태로 처리되어, 외부에서 특정 팝업 페이지로 바로 들어오는 딥링크가 기본적으로 동작하지 않습니다. 여기에 회사 SAML SSO까지 끼면 아래 세 가지 문제가 겹칩니다.
| 문제 | 원인 | 해결 수단 |
|---|---|---|
| 외부 URL로 내부 페이지 접근 불가 | SPA 구조, 단일 엔드포인트 | DeepLink 모듈 |
| 로그인 전 딥링크 URL 소실 | SSO 리디렉션 시 원래 URL 유실 | Force login + LoginLocation 상수 |
| SAML 로그인 후 원래 URL 복귀 | cont 파라미터 전달 여부 | js_SSOLogin 자동 실행 |
Mendix에서 팝업처럼 보이는 화면은 레이아웃만 PopupLayout으로 설정된 일반 Page입니다. 진짜 별도 창이 아니기 때문에 DeepLink 모듈로 충분히 직접 연결할 수 있습니다.
클릭
토큰값
감지
페이지
로그인
팝업 오픈 ✅
실행
복원
완료
클릭
_ReviewMeeting
+ HTML 삽입
팝업 오픈
_Main
포함 메일 발송 ✅
IVK_ShowPage_ReviewMeeting_NewEdit — 복기회의록 Object 생성 + Token 생성 + 딥링크 URL을 Details HTML에 삽입
MF_SendMail_Main — 이미 만들어진 Object를 메일로 발송 (이 MF는 수정 불필요)
Mendix 내부 ID를 URL에 그대로 노출하면 보안상 좋지 않습니다. 별도 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()는 10.x에서 동작하지 않습니다. round()를 활용한 방법 1이 가장 안전합니다.
딥링크 URL이 접근될 때 실행되는 MF입니다. Token으로 Object를 조회하고 페이지를 엽니다.
| 항목 | 값 |
|---|---|
| MF 이름 | MF_DeepLink_OpenReviewMeeting |
| 파라미터 이름 | UrlPath |
| 파라미터 타입 | String |
false → 에러 페이지 또는 홈페이지 Show
true → 다음 단계
빠른 방법: 원래 등록 MF에서 Create 이후 Show Page까지 블록 복사(Ctrl+C) 후 붙여넣고 앞단 Create만 Retrieve로 교체
[MyApp.ReviewMeeting/Token = $UrlPath]
-- Builder 모드에서 설정 시:
-- 왼쪽: Token
-- 가운데: =
-- 오른쪽: $UrlPath (파라미터 선택)
앱 시작 시 어떤 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 |
reviewmeeting으로 설정하면 접근 URL은 /link/reviewmeeting/토큰값 형태가 됩니다. 쿼리스트링(?id=) 방식이 아니라 path 방식으로 토큰이 UrlPath 파라미터에 자동 전달됩니다.
패턴을 확인하려면 DeepLink 모듈 → _Use me → Examples → SetupExampleDeeplinks를 참고하세요.
Mendix App Settings의 After Startup에는 MF를 하나만 등록할 수 있습니다. 기존에 SAML StartSSO가 등록되어 있으므로, 두 MF를 순서대로 호출하는 래퍼 MF를 만들어야 합니다.
[시작]
→ Call Microflow: CustomSAML.StartSSO
→ Call Microflow: MF_Setup_DeepLinks
[끝 — Return type: Boolean / Value: true]
※ End Event 리턴 타입을 Boolean으로 설정하지 않으면 에러 발생
복기회의록 등록 MF(IVK_ShowPage_ReviewMeeting_NewEdit)에서 Token을 생성한 직후 딥링크 버튼 HTML을 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>'
DeepLink.SUB_GetApplicationURL MF가 도커 내부 호스트명을 반환하는 경우 운영 URL을 직접 하드코딩해야 합니다. 개발/운영 분기가 필요하다면 Mendix Constant를 환경별로 다르게 설정하는 방법을 사용하세요.
딥링크 클릭 시 미로그인 상태면 어디로 보낼지, SSO 완료 후 어디로 돌아올지를 상수로 설정합니다.
| 상수명 | 설정값 | 역할 |
|---|---|---|
| LoginLocation | /p/PG_Login | 미로그인 시 이동할 로그인 페이지 |
| SSOHandlerLocation | /SSO/ | SSO 완료 후 딥링크 복원 경로 |
Mendix 10.x에서는 UseDeepLink 같은 별도 활성화 상수가 없으며, After Startup 등록만으로 활성화됩니다.
커스텀 SAML 모듈의 js_SSOLogin JavaScript Action이 현재 URL을 cont 파라미터로 붙여서 /sso로 리디렉션하는 구조입니다.
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 실행 → 팝업 오픈
PG_Login 페이지에 HTML Snippet 위젯을 추가하면 버튼 클릭 없이 자동으로 SSO 페이지로 이동시킬 수 있습니다. 단, Mendix 10.x에서는 On page load 이벤트가 없으므로 아래 방법을 사용합니다.
<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>
| 증상 | 원인 | 해결 |
|---|---|---|
| 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)) 사용 |
✅ 구현 완료 체크리스트
1. 운영 배포 완료 확인 (CICD → 자동 재시작)
2. 복기회의록 새로 등록 (기존 데이터는 Token이 없음)
3. [메일발송] 클릭 → 메일 수신 확인
4. "🔗 시스템 바로가기" 버튼 클릭
5. SSO 로그인 → 복기회의록 팝업 오픈 확인
Mendix 10.12.8 / DeepLink 모듈 10.0.10 기준 · 사내 Mendix Cloud 운영 환경