λ³Έ 글에 λŒ€ν•œ μ½”λ“œλŠ” kdevkr/spring-boot-line-login μ—μ„œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

μš°λ¦¬κ°€ μ΄μš©ν•˜λŠ” 수 λ§Žμ€ μ›Ή μ„œλΉ„μŠ€μ—μ„œλŠ” νšŒμ›κ°€μž… ν•œ 계정 ν˜Ήμ€ μ΄λ©”μΌλ‘œ λ‘œκ·ΈμΈν•˜κΈ° 뿐만 μ•„λ‹ˆλΌ 카카였, 넀이버, ꡬ글, 메타, μ• ν”Œ, κΉƒν—ˆλΈŒμ™€ 같은 μ†Œμ…œ ν”„λ‘œλ°”μ΄λ”μ˜ κ³„μ •μœΌλ‘œ μΈμ¦ν•˜μ—¬ μ‰½κ²Œ λ‘œκ·ΈμΈν•  수 μžˆλŠ” 연동 κΈ°λŠ₯을 μ œκ³΅ν•œλ‹€. κ΅­λ‚΄μ˜ 경우 λŒ€λΆ€λΆ„ 카카였 λ‘œκ·ΈμΈμ΄λ‚˜ 넀이버 λ‘œκ·ΈμΈμ„ μ‚¬μš©ν•˜λŠ” 편인데 라인 ν”ŒλŸ¬μŠ€μ—μ„œ μ œκ³΅ν•˜λŠ” 라인 λ©”μ‹ μ €λŠ” κ΅­λ‚΄ λ³΄λ‹€λŠ” μΌλ³Έμ΄λ‚˜ νƒœκ΅­κ³Ό 같은 ν•΄μ™Έ κ΅­κ°€μ—μ„œ 많이 μ‚¬μš©λ˜λŠ” νŽΈμ΄λ‹€. 라인 ν”ŒλŸ¬μŠ€κ°€ μžˆμ§€λ§Œ 라인 개발자 μ‚¬μ΄νŠΈ 및 개발 λ¬Έμ„œμ˜ 경우 μ˜μ–΄μ™€ μΌλ³Έμ–΄λ§Œ μ§€μ›ν•˜κ³  μžˆλ‹€. λ§Œμ•½, νšŒμ‚¬μ—μ„œ λ§Œλ“œλŠ” μ„œλΉ„μŠ€κ°€ μΌλ³Έμ΄λ‚˜ νƒœκ΅­ 그리고 λ§λ ˆμ‹œμ΄μ•„ κ΅­κ°€μ˜ 고객듀을 λŒ€μƒμœΌλ‘œ ν•œλ‹€λ©΄ 라인 λ©”μ‹ μ €λ₯Ό ν†΅ν•œ 연동 κΈ°λŠ₯ 지원은 거의 ν•„μˆ˜μ μœΌλ‘œ λ„μž…λ  κ°€λŠ₯성이 μžˆλ‹€.

LINE Login Diagram

LINE Developers Console

라인 λΉ„μ¦ˆλ‹ˆμŠ€ μ½˜μ†”μ„ 톡해 λΉ„μ¦ˆλ‹ˆμŠ€ 계정을 생성할 수 있으며 라인 λΉ„μ¦ˆλ‹ˆμŠ€ 계정을 λ§Œλ“  후에 개발자 μ½˜μ†”μ— λ³„λ„λ‘œ μ ‘μ†ν•˜μ—¬ 라인 둜그인 μ΄λ‚˜ λ©”μ‹œμ§€ 채널을 λ“±λ‘ν•˜κ³  μ„€μ •ν•  수 μžˆλ‹€. 라인 ν”Œλž«νΌμ— 연동할 μ„œλΉ„μŠ€ ν”„λ‘œλ°”μ΄λ”λ₯Ό μƒμ„±ν•΄μ•Όν•˜λ©° 라인 둜그인과 λ©”μ‹œμ§• API 채널은 λ³„λ„λ‘œ κ΅¬λΆ„λ˜μ–΄ λ§Œλ“€μ–΄μ§„λ‹€. 각 채널은 λ³„λ„λ‘œ 운영될 수 μžˆμ§€λ§Œ 라인 둜그인 채널에 친ꡬ μ˜΅μ…˜μœΌλ‘œ λ©”μ‹œμ§€ 채널 계정을 μ—°κ²°ν•  수 있게 μ§€μ›ν•œλ‹€.

라인 μ‚¬μš©μžκ°€ 둜그인 채널에 μ—°λ™ν•˜λ”λΌλ„ μ„œλΉ„μŠ€ μ•±μ—μ„œ μ‚¬μš©μžμ—κ²Œ λ©”μ‹œμ§€λ₯Ό 보내기 μœ„ν•΄μ„œλŠ” μ‚¬μš©μžκ°€ λ©”μ‹œμ§€ 채널에 친ꡬ둜 λ“±λ‘λ˜μ–΄μžˆμ–΄μ•Όλ§Œ ν•©λ‹ˆλ‹€.

라인 둜그인 채널 μΆ”κ°€ν•˜κΈ°

μ‚¬μš©μžκ°€ 라인 ν”Œλž«νΌμ„ 톡해 μ„œλΉ„μŠ€μ— 연동할 수 μžˆλ„λ‘ μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜ λ°©μ‹μ˜ 라인 둜그인 채널을 μΆ”κ°€ν•΄μ•Όν•œλ‹€. μ„œλΉ„μŠ€ 지역 μ˜΅μ…˜μ˜ 경우 일본 β€’ νƒœκ΅­ β€’ λŒ€λ§Œ β€’ 인도넀이사 뿐이며 ν•œκ΅­μ„ 선택할 수 μ—†λŠ”κ²Œ μ˜μ•„ν•˜κΈ΄ ν•˜μ§€λ§Œ κ΅­λ‚΄μ˜ 경우 κ°€μž₯ κ°€κΉŒμš΄ 일본을 μ„ νƒν•˜λ©΄ 될 것 κ°™λ‹€.

라인 둜그인 콜백 μ£Όμ†Œ μ„€μ •

라인 둜그인 채널을 μΆ”κ°€ν–ˆλ‹€λ©΄ LINE Login μ„€μ • νŽ˜μ΄μ§€λ‘œ μ΄λ™ν•˜μ—¬ 라인 둜그인 κ³Όμ •μ—μ„œ 라인 ν”Œλž«νΌμ΄ 인증된 μ½”λ“œλ₯Ό 전달해쀄 μ„œλΉ„μŠ€ 콜백 μ£Όμ†Œλ₯Ό 등둝해두어야 ν•œλ‹€. λ°˜λ“œμ‹œ λ°±μ—”λ“œ μ„œλ²„ μ£Όμ†Œκ°€ 콜백 μ£Όμ†ŒμΌ ν•„μš”λŠ” μ—†μœΌλ©° ν”„λ‘ νŠΈμ—”λ“œμ—μ„œ μ½œλ°±μ„ 받은 ν›„ μ½”λ“œκ°’μ„ λ°±μ—”λ“œμ— REST API둜 전달해도 λ¬΄λ°©ν•˜λ‹€. 콜백 μ£Όμ†ŒλŠ” κ°œν–‰μœΌλ‘œ μ—¬λŸ¬κ°œλ₯Ό λ“±λ‘ν•˜μ—¬ μ‚¬μš©ν•  수 μžˆλ„λ‘ μ§€μ›ν•œλ‹€.

Callback URL
https://access.line.me/oauth2/v2.1/authorize?response_type=code&client_id={LOGIN_CHANNEL_ID}&redirect_uri={CALLBACK_URL}

콜백 μ£Όμ†ŒλŠ” μ„œλΉ„μŠ€μ—μ„œ 인증 μ½”λ“œλ‘œ μ•‘μ„ΈμŠ€ 토큰을 λ°œκΈ‰ν•˜λŠ” κ²½μš°μ—λ„ μ‚¬μš©μž 둜그인 μ‹œ μ‚¬μš©λœ λ™μΌν•œ 콜백 μ£Όμ†Œλ₯Ό μš”κ΅¬ν•˜λ―€λ‘œ λ°±μ—”λ“œ μ„œλ²„μ—μ„œλ„ 채널 아이디와 채널 μ‹œν¬λ¦Ώ 뿐만 μ•„λ‹ˆλΌ λ³„λ„λ‘œ 콜백 μ£Όμ†Œλ₯Ό κ΄€λ¦¬ν•΄μ•Όν•©λ‹ˆλ‹€.

OIDC 이메일 κΆŒν•œ μš”μ²­

μ„œλΉ„μŠ€ μ—°λ™μ‹œ μ‚¬μš©μžκ°€ μ‚¬μš©ν•˜λŠ” 이메일 μ£Όμ†Œκ°€ λ°˜λ“œμ‹œ ν•„μš”ν•˜λ‹€λ©΄ 이메일 νšλ“ κΆŒν•œμ„ μœ„ν•΄μ„œ 둜그인 채널 μ˜΅μ…˜μ˜ OpenID Connect에 λŒ€ν•œ 이메일 μ£Όμ†Œ κΆŒν•œμ„ λ³„λ„λ‘œ ν™œμ„±ν™” ν•΄μ•Όν•œλ‹€. μ‹€μ œλ‘œλŠ” 이메일을 μ–΄λ–»κ²Œ μ‚¬μš©ν•˜λŠ”μ§€μ— λŒ€ν•œ μŠ€ν¬λ¦°μƒ·μ„ μ—…λ‘œλ“œ ν•΄μ•Όν•˜κ² μ§€λ§Œ 개발 λ‹¨κ³„μ—μ„œλŠ” μž„μ˜μ˜ 이미지λ₯Ό 등둝해도 ν—ˆμš©λœλ‹€. μ‚¬μš©μž 둜그인 μ‹œ μ „λ‹¬ν•˜λŠ” URL νŒŒλΌλ―Έν„° 쀑 μŠ€μ½”ν”„μ— μ•„λž˜μ™€ 같이 email을 μΆ”κ°€ν•˜λ©΄ 이메일에 λŒ€ν•œ κΆŒν•œ μ˜΅μ…˜μ΄ UI에 λ…ΈμΆœλ  것이닀.



profile+openid+email
https://access.line.me/oauth2/v2.1/authorize?response_type=code&client_id={LOGIN_CHANNEL_ID}&scope=profile%20openid%20email

μ‚¬μš©μž 인증 ν™”λ©΄μ—μ„œ 이메일 μ£Όμ†Œ κΆŒν•œμ„ ν•„μˆ˜λ‘œ μš”κ΅¬ν•˜λŠ” μ˜΅μ…˜μ€ μ§€μ›ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

OAuth v2.1 μ•‘μ„ΈμŠ€ 토큰 λ°œκΈ‰

μ‚¬μš©μž 둜그인 ν›„ μ½œλ°±λ˜μ–΄ μ „λ‹¬λ˜λŠ” URL에 ν¬ν•¨λœ code νŒŒλΌλ―Έν„°λ₯Ό μ‚¬μš©ν•˜μ—¬ μ„œλ²„μ—μ„œλŠ” μ•‘μ„ΈμŠ€ 토큰을 λ°œκΈ‰ν•  수 μžˆλ‹€. OpenID Connect 에 따라 μ•‘μ„ΈμŠ€ 토큰과 ν•¨κ»˜ ID Token이 μ œκ³΅λ˜λŠ”λ° JWT ν˜•μ‹μœΌλ‘œ κ΅¬μ„±λœ λ¬Έμžμ—΄μ΄λ―€λ‘œ νŽ˜μ΄λ‘œλ“œλ₯Ό ν™•μΈν•˜κ±°λ‚˜ Verify ID token을 톡해 토큰 검증과 ν•¨κ»˜ λΆ„μ„λœ κ²°κ³Όλ₯Ό μ‘λ‹΅μœΌλ‘œ λ°›μ•„λ³Ό 수 μžˆλ‹€.

String idToken = response.getIdToken();
String payload = idToken.split("\\.")[1];
Map<String, Object> claims = objectMapper.readValue(new String(Base64.getUrlDecoder().decode(payload)), new TypeReference<>(){});
{
  "iss": "https://access.line.me",
  "sub": "U1234567890abcdef1234567890abcdef",
  "aud": "1234567890",
  "exp": 1504169092,
  "iat": 1504263657,
  "nonce": "0987654asdf",
  "amr": ["pwd"],
  "name": "Taro Line",
  "picture": "https://sample_line.me/aBcdefg123456",
  "email": "taro.line@example.com"
}

JWT νŽ˜μ΄λ‘œλ“œμ— ν¬ν•¨λ˜λŠ” ν•­λͺ© 쀑 sub λŠ” 라인 μ‚¬μš©μžμ— λŒ€ν•œ User IDλ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€.


λ©”μ‹œμ§€ 채널과 μ—°λ™ν•˜κΈ° (친ꡬ μΆ”κ°€ μ˜΅μ…˜)

라인 둜그인 κΈ°λŠ₯을 λ„μž…ν•˜λ”λΌλ„ 둜그인 채널과 λ©”μ‹œμ§€ 채널은 λ³„λ„λ‘œ λΆ„λ¦¬λ˜μ–΄μžˆμ–΄ λ©”μ‹œμ§€ 채널을 λ³„λ„λ‘œ μƒμ„±ν•œ ν›„ 둜그인 μ±„λ„μ—μ„œ λ©”μ‹œμ§€ 채널에 등둝할 수 μžˆλŠ” κΈ°λŠ₯을 ν™œμ„±ν™”ν•˜κ³  μ‚¬μš©μžμ—κ²Œ 친ꡬ μΆ”κ°€λ₯Ό μš”κ΅¬ν•΄μ•Όν•œλ‹€. 친ꡬ μΆ”κ°€ μ˜΅μ…˜(Add friend option)에 λ©”μ‹œμ§€ 채널을 μ„ νƒν•œλ‹€λ©΄ 둜그인 연동 μ‹œ μ‚¬μš©ν•  수 μžˆλŠ” bot_prompt νŒŒλΌλ―Έν„°μ— 값에 따라 친ꡬ μΆ”κ°€ μ˜΅μ…˜ λ…ΈμΆœ 방식을 μ œκ³΅ν•  수 μžˆλ‹€.

https://client.example.org/cb?code={CODE}&state={STATE}&friendship_status_changed={FRIENDSHIP_STATUS_CHANGED}

친ꡬ μΆ”κ°€ μ˜΅μ…˜μ„ μ‚¬μš©ν•˜λŠ” κ²½μš°μ— μ‚¬μš©μž 둜그인 ν›„ 콜백 μ‹œ μ „λ‹¬λ˜λŠ” μ½”λ“œ νŒŒλΌλ―Έν„° 이외에 friendship_status_changed νŒŒλΌλ―Έν„°κ°€ μΆ”κ°€μ μœΌλ‘œ μ „λ‹¬λ˜μ–΄ ν•΄λ‹Ή μ‚¬μš©μžκ°€ 친ꡬ μΆ”κ°€λ₯Ό μˆ˜ν–‰ν–ˆλŠ”μ§€ μ—¬λΆ€λ₯Ό 확인할 수 μžˆλ‹€. λ§Œμ•½, 둜그인 화면에 λ©”μ‹œμ§€ 채널을 친ꡬ둜 μΆ”κ°€ν•  수 μžˆλŠ” λ²„νŠΌμ΄ λ…ΈμΆœλ˜μ§€ μ•ŠλŠ”λ‹€λ©΄ μ•„λž˜μ™€ 같은 ν•­λͺ©μ„ μ œλŒ€λ‘œ μ„€μ •ν–ˆλŠ”μ§€ λ‹€μ‹œ ν•œλ²ˆ 체크해보도둝 ν•˜μž.

μ‚¬μš©μžμ—κ²Œ λ©”μ‹œμ§€ 보내기

μ‚¬μš©μžκ°€ λ©”μ‹œμ§€ 채널에 친ꡬ둜 λ“±λ‘ν•˜μ˜€λ‹€λ©΄ 둜그인 연동을 μˆ˜ν–‰ν•œ μ‚¬μš©μžμ—κ²Œ λ©”μ‹œμ§€λ₯Ό 보낼 수 μžˆλ‹€. μ‚¬μš©μž ν”„λ‘œν•„ 정보λ₯Ό ν¬ν•¨ν•˜κ³  μžˆλŠ” JWT ν˜•μ‹μ˜ IDToken의 ν•­λͺ© 쀑 sub κ°€ λΌμΈμ—μ„œ μ œκ³΅ν•˜λŠ” APIμ—μ„œ λ‚΄λΆ€μ μœΌλ‘œ μ‚¬μš©ν•  수 μžˆλŠ” User ID이며 Messaging API μ—μ„œλŠ” User IDλ₯Ό μ‚¬μš©ν•˜μ—¬ μ‚¬μš©μžμ—κ²Œ λ©”μ‹œμ§€λ₯Ό 보낼 수 μžˆλ„λ‘ μ œκ³΅ν•œλ‹€.

line:
  bot:
    channel-token: WQ9SQjcWBJqD020+ri***
    channel-secret: 1ba24f197605a2***

User IDλŠ” U1234567890abcdef1234567890abcdef 와 같이 UXXX 둜 μ‹œμž‘ν•˜λŠ” κ°’ μž…λ‹ˆλ‹€.
Line Java SDK μ—μ„œ 채널 토큰은 λ©”μ‹œμ§€ μ±„λ„μ˜ 아이디가 μ•„λ‹Œ Messaging API의 μ•‘μ„ΈμŠ€ ν† ν°μž„μ„ μ£Όμ˜ν•΄μ•Όν•©λ‹ˆλ‹€.

라인 둜그인 인증 ν™”λ©΄ κ΅­μ œν™”

ui_locales νŒŒλΌλ―Έν„°μ— λ‘œμΌ€μΌμ„ μ „λ‹¬ν•˜μ—¬ μ‚¬μš©μžκ°€ 라인 ν”Œλž«νΌμ— μΈμ¦ν•˜κΈ° μœ„ν•œ 화면에 λŒ€ν•΄ κ΅­μ œν™”λ₯Ό μ μš©ν•  수 μžˆλ‹€. λ˜ν•œ, 라인 둜그인 채널 μ„€μ •μ—μ„œ Localization 섀정을 톡해 채널 이름과 μ„€λͺ… 뢀뢄을 언어에 따라 ν‘œμ‹œλ˜λ„λ‘ μ„€μ •ν•  수 μžˆλ‹€. 단, 친ꡬ μ˜΅μ…˜μœΌλ‘œ ν‘œμ‹œλ˜λŠ” λ©”μ‹œμ§€ 채널에 λŒ€ν•œ 이름은 λ³„λ„λ‘œ μ§€μ›ν•˜μ§€ μ•ŠλŠ”λ‹€.

https://access.line.me/oauth2/v2.1/authorize?response_type=code&client_id={LOGIN_CHANNEL_ID}&redirect_uri={CALLBACK_URL}&ui_locales=ja_JP