Developers
제휴사 연동

ⓑ 호스팅 로그인 페이지

제휴사 로그인 페이지에서 인증한 뒤 쏠브 콜백을 호출하는 방식입니다. 소셜 로그인을 운영하는 제휴사용입니다.

쏠브 앱이 제휴사의 로그인 페이지를 열면, 회원은 평소처럼 제휴사 사이트에서 로그인합니다. 로그인이 끝나면 제휴사 서버가 쏠브 콜백 API 를 호출하고, 받은 redirect_url 로 회원을 보내면 연동이 완료됩니다. 카카오·네이버·구글·Apple 같은 소셜 로그인을 운영하거나, 자체 ID/PW 와 소셜 로그인을 함께 운영하는 제휴사는 이 방식을 사용합니다.

쏠브가 전달해 드리는 값

계약 후 쏠브가 콜백 API URL, 제휴사의 platform_type(숫자), 콜백 인증 시크릿을 전달합니다. 제휴사는 쏠브 전용 로그인 페이지 URL 을 쏠브에 알려주세요.

흐름

  1. 회원 → 제휴사: 책 구매. 회원이 제휴사 사이트에서 책을 삽니다. 여기까지는 지금과 같습니다.
  2. 회원 → 제휴사: 로그인 화면 열기. 쏠브 앱에서 "제휴사 연동하기"를 누르면, 앱 안에 제휴사 로그인 화면이 열립니다.
  3. 회원 → 제휴사: 평소처럼 로그인. 회원은 아이디나 카카오·네이버·구글 등 평소 쓰던 방법으로 로그인합니다.
  4. 제휴사 → 쏠브: "100023번 회원 로그인했어요". 로그인이 끝나면 제휴사 서버가 쏠브에 회원 번호를 알려 줍니다. 쏠브는 돌아갈 주소를 답해 줍니다.
  5. 제휴사 → 회원: 받은 주소로 이동. 제휴사가 회원 화면을 그 주소로 보내면 연동이 끝납니다. 같은 화면 안에서 이동해야 합니다.
  6. 쏠브 → 제휴사: "이 회원 뭐 샀어요?". 쏠브가 제휴사에 이 회원이 지금 볼 수 있는 상품을 물어봅니다.
  7. 제휴사 → 쏠브: 상품코드 목록. 제휴사는 구매한 상품의 코드 목록으로 답합니다. 환불된 상품은 빼고 보냅니다.
  8. 쏠브 → 회원: 책장에 책 추가. 쏠브가 상품코드로 전자책을 찾아 회원의 책장에 넣습니다. 상품코드는 파트너 어드민에 미리 등록해 둡니다.

1단계. 쏠브 전용 로그인 페이지 준비

  • 쏠브 앱은 등록된 URL 을 그대로 엽니다. 쿼리 파라미터를 붙이지 않습니다.
  • 일반 로그인과 구분할 수 있도록 쏠브 전용 URL(예: https://www.partner.example.com/solve/login)을 따로 두세요. 이 URL 로 들어온 로그인만 쏠브 콜백으로 이어집니다.
  • 화면 구성과 인증 방식은 자유입니다. 기존 로그인 화면을 그대로 써도 됩니다.
  • 소셜 로그인처럼 외부 사이트를 다녀오는 경우, 세션에 "쏠브 연동 중" 표시를 남겨 두었다가 로그인이 끝나는 시점에 2단계를 진행하세요.

2단계. 로그인 성공 후 쏠브 콜백 호출

로그인에 성공했을 때만 제휴사 서버에서 호출합니다. 콜백 인증 시크릿이 들어가므로 브라우저에서 호출하면 안 됩니다.

콜백 요청 (curl 로 재현)
curl -X POST '<쏠브가 전달한 콜백 API URL>' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <쏠브가 발급한 콜백 인증 시크릿>' \
  -d '{"id": "100023", "platform_type": <쏠브가 부여한 platform_type>}'
헤더값설명
AuthorizationBearer <시크릿>쏠브가 제휴사별로 발급한 콜백 인증 시크릿. 서버 설정(환경변수 등)에만 두고 로그·브라우저에 노출하지 마세요.
필드타입필수설명
idstring필수회원의 불변·유일 식별자(= user_key), 최대 255자
platform_typenumber필수쏠브가 부여한 제휴사 식별자
solve_sso_verify_tokenstring선택과거 버전 호환용입니다. 보내도 무시하며 생략해도 됩니다.

id 에는 소셜 계정 ID·이메일을 넣지 마세요

카카오·네이버 등으로 로그인했더라도 제휴사 내부 회원의 불변 식별자(회원번호 등)를 보내야 합니다. 값이 바뀌면 회원은 연동과 책장의 책을 잃고, 탈퇴한 회원의 값을 다른 회원에게 다시 주면 안 됩니다.

응답

상태 코드본문의미와 처리
200{ "redirect_url": "https://..." }3단계로 진행합니다.
400{ "error": "BadRequest", "message": "..." }platform_type 이 틀렸거나 비활성 상태입니다. 쏠브에 문의해 주세요.
401{ "error": "Unauthorized", "message": "..." }인증 시크릿이 없거나 틀렸습니다. 재시도하지 말고 설정을 확인하세요.
429쏠브 콜백은 분당 600회까지 받습니다. 호출 한도를 넘었습니다. 응답의 Retry-After 헤더(초)만큼 기다린 뒤 다시 시도하세요.
500{ "error": "InternalServerError", "message": "..." }쏠브 일시 오류입니다. 회원에게 잠시 후 다시 시도하도록 안내하세요.

3단계. 같은 웹뷰에서 redirect_url 로 이동

받은 redirect_url 로 회원의 브라우저를 그대로 이동시킵니다(HTTP 302 또는 window.location.href). URL 에는 쏠브가 위변조 방지용 서명 파라미터를 함께 담아 보내므로, 파라미터를 빼거나 순서를 바꾸는 등 어떤 수정도 하지 마세요.

새 창·다른 브라우저로 열면 연동이 실패합니다

쏠브는 연동을 시작한 웹뷰에 1회용 토큰을 발급해 두고, redirect_url 로 돌아왔을 때 확인합니다. 로그인부터 이동까지 쏠브 앱이 연 같은 웹뷰 안에서 이어져야 합니다. target="_blank", 외부 브라우저 열기, 팝업 로그인 뒤 부모 창 이동 등을 쓰지 마세요.

재생 공격·CSRF 방지는 이 1회용 토큰으로 쏠브가 처리하므로, 제휴사가 state·nonce 를 따로 구현할 필요는 없습니다.

구현 예시

제휴사 로그인이 성공한 직후 호출하는 함수입니다. 일반 로그인 핸들러와 소셜 로그인 콜백 핸들러 양쪽에서, "쏠브 연동 중"인 세션일 때만 호출하세요.

// 제휴사 로그인 성공 직후, 쏠브 연동 중인 세션에서만 호출
async function completeSolveLink(req, res, member) {
  const response = await fetch(process.env.SOLVE_CALLBACK_URL, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${process.env.SOLVE_CALLBACK_SECRET}`, // 쏠브가 발급한 콜백 인증 시크릿
    },
    body: JSON.stringify({
      id: String(member.memberNo), // 소셜 ID 가 아닌 내부 회원번호
      platform_type: Number(process.env.SOLVE_PLATFORM_TYPE),
    }),
    signal: AbortSignal.timeout(10_000),
  });

  if (!response.ok) {
    console.error('solve callback failed', response.status);
    return res.status(502).send('쏠브 연동 중 오류가 발생했습니다. 잠시 후 다시 시도해 주세요.');
  }

  const { redirect_url } = await response.json();
  delete req.session.solveLinking;
  return res.redirect(302, redirect_url); // 같은 웹뷰에서 이동
}

콜백을 미리 시험하기

콜백 주소와 시크릿은 계약 뒤에 받지만, 그 전에도 제휴사 로그인 페이지가 콜백을 규약대로 보내는지 확인할 수 있습니다. solve-callback-mock.mjs 내려받기로 자기 PC 에 "쏠브 콜백 API 흉내"를 띄우세요. 파일 하나이며 Node.js 18 이상만 있으면 설치할 것이 없고, 받기만 할 뿐 밖으로는 아무것도 보내지 않습니다. 쏠브 서버와는 아무 관계가 없습니다.

시험용 시크릿과 platform_type 을 환경변수로 넘겨 실행합니다. 시크릿은 직접 정하되 쏠브가 받아 주는 값과 같은 조건이어야 합니다 — 32자 이상 4096자 이하, 영문·숫자·기호(공백 포함)만, 앞뒤 공백 없이. 쏠브는 32자 미만의 콜백 시크릿을 쓸 수 없는 값으로 보고 모든 콜백을 401 로 거절하므로, 짧은 값으로는 도구가 시작하지 않습니다. platform_type 은 쏠브가 부여하는 양의 정수입니다(0 이나 소수는 안 됩니다).

콜백 흉내 도구 실행 (macOS·Linux)
SOLVE_MOCK_CALLBACK_SECRET=<시험용 값> SOLVE_MOCK_PLATFORM_TYPE=<숫자> node solve-callback-mock.mjs
콜백 흉내 도구 실행 (Windows PowerShell)
$env:SOLVE_MOCK_CALLBACK_SECRET = "<시험용 값>"; $env:SOLVE_MOCK_PLATFORM_TYPE = "<숫자>"; node solve-callback-mock.mjs

도구가 시작하면 http://127.0.0.1:4310/solve-callback 처럼 콜백 주소를 알려 줍니다. 제휴사 서버의 "쏠브 콜백 URL" 을 그 주소로, 콜백 시크릿을 위에서 정한 시험용 값으로, platform_type 을 같은 숫자로 바꾼 뒤 자기 로그인 페이지에서 로그인해 보세요. 쏠브가 계약 뒤에 전달하는 진짜 콜백 시크릿은 이 도구에 넣지 마세요.

확인하는 것결과
정상 요청200 과 redirect_url
시크릿이 없거나 틀림401
id 가 문자열이 아니거나 비었거나 256자 이상, platform_type 이 양의 정수가 아니거나 없거나 다름, solve_sso_verify_token 이 있는데 문자열이 아님(null 포함), Content-Type 이 JSON 이 아님400
platform_type 이 숫자 모양의 문자열200, 단 콘솔에 "숫자로 보내세요" 주의
POST 가 아닌 요청405

본문이 틀리면 시크릿이 틀려도 400 입니다 — 쏠브도 인증보다 본문을 먼저 보기 때문이며, 콘솔 줄에는 시크릿 문제도 함께 나옵니다. 요청마다 콘솔에 점검 결과가 한 줄씩 나옵니다. 시크릿 값은 찍지 않고 "일치"·"불일치"만 알려 줍니다. 받은 요청의 본문·헤더·주소 원문도 화면에 싣지 않고, id 는 길이만, 필드는 이름이 아닌 통과 여부만 알려 줍니다. --next 429 또는 --next 500 을 붙이면 다음 정상 요청 한 번에 그 응답(429 는 Retry-After: 1)을 돌려주므로 제휴사의 오류 처리도 시험할 수 있습니다. --port·--host 로 주소를 바꿀 수 있고, --host 를 127.0.0.1 밖으로 바꾸면 같은 네트워크의 다른 기기에서도 접근됩니다.

도구가 돌려준 redirect_url 은 /done 주소입니다. 제휴사 서버가 이 주소로 회원의 브라우저를 수정 없이 보내면 "연동 흉내가 끝났습니다" 화면에 PASS 가 나오고, 쿼리를 하나라도 바꾸면 FAIL 과 달라진 값의 개수(빠짐·값이 바뀜·추가됨)가 나옵니다. 이름과 값은 화면에 싣지 않습니다. 쏠브가 만든 연동 주소의 서명은 10분 뒤 만료되므로, 도구도 redirect_url 을 받은 지 10분이 지나서 열면 FAIL 로 알립니다. 주소의 sig 같은 값은 서명처럼 보이게 만든 임의 값이며 진짜 서명이 아닙니다.

구현 체크리스트

  • 쏠브 전용 로그인 URL 을 쏠브에 전달했다 (쿼리 파라미터 없이 동작)
  • 로그인에 성공했을 때만, 제휴사 서버에서 Authorization: Bearer <시크릿> 을 담아 콜백을 호출한다
  • 콜백 인증 시크릿이 브라우저·로그에 노출되지 않는다
  • id 로 소셜 계정 ID·이메일이 아닌 내부 회원의 불변 식별자를 보낸다
  • redirect_url 을 수정 없이, 같은 웹뷰에서 연다
  • 소셜 로그인으로 외부를 다녀와도 "쏠브 연동 중" 상태가 유지된다

관련 문서

이 페이지 목차