Platform Notes
iOS Swift deep link 설정 차이
iOS 문서는 공식 SDK가 아니라 모바일 공식 흐름을 iOS에 맞게 적용하기 위한 짧은 설정 메모입니다.
이 문서가 맞는 경우
플랫폼별 권장 흐름을 먼저 고정한 뒤, code 교환은 모두 앱 서버에서 처리합니다.
Best for- iOS UIKit, SwiftUI, iPadOS 앱
Strategy- ASWebAuthenticationSession + Universal Link + backend token exchange
Callback- Universal Link를 우선 사용하고 custom scheme은 fallback으로만 검토합니다.
Support- 참고 메모: 플랫폼별 deep link 설정 차이만 설명
공식 SDK 문서가 아닙니다
준비물
아래 값은 모바일 공식 흐름을 각 플랫폼 deep link 설정에 연결할 때 필요합니다.
issuer
모든 플랫폼에서 canonical issuer/API base URL은 https://verify.myknow.xyz 입니다
client_id
Developer Portal에서 승인된 public 또는 confidential client id
redirect_uri
client 설정에 exact match로 등록된 callback URL 또는 deep link
scope
ssafy.verify는 필수. 기수/캠퍼스/지역은 ssafy.affiliation, 이름은 ssafy.name, 이미지는 ssafy.profile_image 추가
Mattermost id
기존 Mattermost 인증 프로젝트의 계정 매핑이 필요한 경우에만 ssafy.mattermost_id 추가
backend endpoint
앱 서버에서 code와 code_verifier를 받아 /verify/token으로 교환
WebView unsupported
client secret 금지
적용 흐름
공식 흐름
/docs/platforms/mobile의 hosted page + backend exchange 계약을 따름
iOS 차이
ASWebAuthenticationSession으로 시스템 브라우저 인증을 열기
callback
Universal Link 또는 custom scheme에서 state를 비교한 뒤 backend로 code 전달
iOS 설정 메모
SSAFY Verify가 공식 유지하는 범위는 protocol과 hosted page입니다. Swift SDK 코드는 앱 팀 책임입니다.
붙일 위치
iOS 앱의 Associated Domains와 인증 시작 로직
확인 방법
WebView가 아니라 ASWebAuthenticationSession으로 열림
ios-deep-link.ymliOS deep link와 시스템 브라우저 선택 기준platform: iOS
recommended_callback: Universal Link
example_redirect_uri: https://partner.example.com/ios/ssafy/callback
system_browser: ASWebAuthenticationSession
fallback_callback: partnerapp://ssafy/callback
notes:
- Universal Link domain must be controlled by the partner app.
- callbackURLScheme is only needed for custom scheme fallback.
- SSAFY Verify does not officially maintain Swift SDK code.공통 서버 token exchange 계약
플랫폼이 무엇이든 최종 교환과 verification_token 검증은 앱 서버에서 수행합니다.
Client request- 앱 또는 브라우저가 자기 backend로 보내는 JSON
Backend action- backend가 /verify/token에 grant_type=verification_code로 교환
Backend response- 앱 세션에 저장해도 되는 최소 인증 결과만 반환
client-to-backend.json앱이 자기 서버에 보내는 body{
"code": "code_from_callback",
"codeVerifier": "pkce_verifier_from_client",
"redirectUri": "https://partner.example.com/ssafy",
"iss": "https://verify.myknow.xyz"
}Client request fields
code?- callback으로 받은 1회성 Verify code
codeVerifier?- PKCE 검증에 필요한 원본 verifier
redirectUri?- 외부 앱에 등록된 callback URL
iss?- callback 응답의 issuer
backend-success.json앱 서버가 클라이언트에 돌려주는 최소 결과{
"ok": true,
"verified": true,
"sub": "pairwise_subject_placeholder",
"cohort": "15",
"campus": "서울 캠퍼스",
"authTime": 1781740800
}Backend response fields
ok?- 외부 앱 backend 처리 성공 여부
verified?- SSAFY 구성원 인증 완료 여부
sub?- client별 pairwise subject
cohort?- SSAFY 기수
campus?- SSAFY 캠퍼스
authTime?- JWT auth_time NumericDate seconds
보안 체크리스트
공식 지원 범위
protocol, hosted page, backend token exchange만 공식 지원
WebView
Unsupported / Do not use. 인증 요청을 embedded WebView에서 열지 않음
secret 위치
client_secret은 confidential client의 서버 환경변수에만 저장
state 검증
authorize 시작 시 만든 state와 callback state를 반드시 비교
PKCE 보관
code_verifier는 callback 완료 후 서버 교환까지만 짧게 보관
token 검증
verification_token은 서버에서 iss, aud, exp, sub, client_id, verified, auth_time, amr, acr를 검증
저장 최소화
앱 DB에는 verified, sub, cohort, campus, verifiedAt 정도만 저장
Mattermost id
ssafy.mattermost_id는 기존 MM 인증 계정 매핑 목적일 때만 요청하고 저장