λΌμΈ λ‘κ·ΈμΈ μ°λ
λ³Έ κΈμ λν μ½λλ kdevkr/spring-boot-line-login μμ νμΈν μ μμ΅λλ€.
μ°λ¦¬κ° μ΄μ©νλ μ λ§μ μΉ μλΉμ€μμλ νμκ°μ ν κ³μ νΉμ μ΄λ©μΌλ‘ λ‘κ·ΈμΈνκΈ° λΏλ§ μλλΌ μΉ΄μΉ΄μ€, λ€μ΄λ², ꡬκΈ, λ©ν, μ ν, κΉνλΈμ κ°μ μμ νλ‘λ°μ΄λμ κ³μ μΌλ‘ μΈμ¦νμ¬ μ½κ² λ‘κ·ΈμΈν μ μλ μ°λ κΈ°λ₯μ μ 곡νλ€. κ΅λ΄μ κ²½μ° λλΆλΆ μΉ΄μΉ΄μ€ λ‘κ·ΈμΈμ΄λ λ€μ΄λ² λ‘κ·ΈμΈμ μ¬μ©νλ νΈμΈλ° λΌμΈ νλ¬μ€μμ μ 곡νλ λΌμΈ λ©μ μ λ κ΅λ΄ 보λ€λ μΌλ³Έμ΄λ νκ΅κ³Ό κ°μ ν΄μΈ κ΅κ°μμ λ§μ΄ μ¬μ©λλ νΈμ΄λ€. λΌμΈ νλ¬μ€κ° μμ§λ§ λΌμΈ κ°λ°μ μ¬μ΄νΈ λ° κ°λ° λ¬Έμμ κ²½μ° μμ΄μ μΌλ³Έμ΄λ§ μ§μνκ³ μλ€. λ§μ½, νμ¬μμ λ§λλ μλΉμ€κ° μΌλ³Έμ΄λ νκ΅ κ·Έλ¦¬κ³ λ§λ μμ΄μ κ΅κ°μ κ³ κ°λ€μ λμμΌλ‘ νλ€λ©΄ λΌμΈ λ©μ μ λ₯Ό ν΅ν μ°λ κΈ°λ₯ μ§μμ κ±°μ νμμ μΌλ‘ λμ λ κ°λ₯μ±μ΄ μλ€.
LINE Developers Console
λΌμΈ λΉμ¦λμ€ μ½μμ ν΅ν΄ λΉμ¦λμ€ κ³μ μ μμ±ν μ μμΌλ©° λΌμΈ λΉμ¦λμ€ κ³μ μ λ§λ νμ κ°λ°μ μ½μμ λ³λλ‘ μ μνμ¬ λΌμΈ λ‘κ·ΈμΈ μ΄λ λ©μμ§ μ±λμ λ±λ‘νκ³ μ€μ ν μ μλ€. λΌμΈ νλ«νΌμ μ°λν μλΉμ€ νλ‘λ°μ΄λλ₯Ό μμ±ν΄μΌνλ©° λΌμΈ λ‘κ·ΈμΈκ³Ό λ©μμ§ API μ±λμ λ³λλ‘ κ΅¬λΆλμ΄ λ§λ€μ΄μ§λ€. κ° μ±λμ λ³λλ‘ μ΄μλ μ μμ§λ§ λΌμΈ λ‘κ·ΈμΈ μ±λμ μΉκ΅¬ μ΅μ μΌλ‘ λ©μμ§ μ±λ κ³μ μ μ°κ²°ν μ μκ² μ§μνλ€.
λΌμΈ μ¬μ©μκ° λ‘κ·ΈμΈ μ±λμ μ°λνλλΌλ μλΉμ€ μ±μμ μ¬μ©μμκ² λ©μμ§λ₯Ό 보λ΄κΈ° μν΄μλ μ¬μ©μκ° λ©μμ§ μ±λμ μΉκ΅¬λ‘ λ±λ‘λμ΄μμ΄μΌλ§ ν©λλ€.
λΌμΈ λ‘κ·ΈμΈ μ±λ μΆκ°νκΈ°
μ¬μ©μκ° λΌμΈ νλ«νΌμ ν΅ν΄ μλΉμ€μ μ°λν μ μλλ‘ μΉ μ ν리μΌμ΄μ λ°©μμ λΌμΈ λ‘κ·ΈμΈ μ±λμ μΆκ°ν΄μΌνλ€. μλΉμ€ μ§μ μ΅μ μ κ²½μ° μΌλ³Έ β’ νκ΅ β’ λλ§ β’ μΈλλ€μ΄μ¬ λΏμ΄λ©° νκ΅μ μ νν μ μλκ² μμνκΈ΄ νμ§λ§ κ΅λ΄μ κ²½μ° κ°μ₯ κ°κΉμ΄ μΌλ³Έμ μ ννλ©΄ λ κ² κ°λ€.
λΌμΈ λ‘κ·ΈμΈ μ½λ°± μ£Όμ μ€μ
λΌμΈ λ‘κ·ΈμΈ μ±λμ μΆκ°νλ€λ©΄ LINE Login μ€μ νμ΄μ§λ‘ μ΄λνμ¬ λΌμΈ λ‘κ·ΈμΈ κ³Όμ μμ λΌμΈ νλ«νΌμ΄ μΈμ¦λ μ½λλ₯Ό μ λ¬ν΄μ€ μλΉμ€ μ½λ°± μ£Όμλ₯Ό λ±λ‘ν΄λμ΄μΌ νλ€. λ°λμ λ°±μλ μλ² μ£Όμκ° μ½λ°± μ£ΌμμΌ νμλ μμΌλ©° νλ‘ νΈμλμμ μ½λ°±μ λ°μ ν μ½λκ°μ λ°±μλμ REST APIλ‘ μ λ¬ν΄λ 무방νλ€. μ½λ°± μ£Όμλ κ°νμΌλ‘ μ¬λ¬κ°λ₯Ό λ±λ‘νμ¬ μ¬μ©ν μ μλλ‘ μ§μνλ€.
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μ λ ΈμΆλ κ²μ΄λ€.
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 νλΌλ―Έν°κ° μΆκ°μ μΌλ‘ μ λ¬λμ΄ ν΄λΉ μ¬μ©μκ° μΉκ΅¬ μΆκ°λ₯Ό μννλμ§ μ¬λΆλ₯Ό νμΈν μ μλ€. λ§μ½, λ‘κ·ΈμΈ νλ©΄μ λ©μμ§ μ±λμ μΉκ΅¬λ‘ μΆκ°ν μ μλ λ²νΌμ΄ λ ΈμΆλμ§ μλλ€λ©΄ μλμ κ°μ νλͺ©μ μ λλ‘ μ€μ νλμ§ λ€μ νλ² μ²΄ν¬ν΄λ³΄λλ‘ νμ.
- Link a LINE Official Account with your channel
- Redirect users to the LINE Login authorization URL with the bot_prompt query parameter
μ¬μ©μμκ² λ©μμ§ λ³΄λ΄κΈ°
μ¬μ©μκ° λ©μμ§ μ±λμ μΉκ΅¬λ‘ λ±λ‘νμλ€λ©΄ λ‘κ·ΈμΈ μ°λμ μνν μ¬μ©μμκ² λ©μμ§λ₯Ό λ³΄λΌ μ μλ€. μ¬μ©μ νλ‘ν μ 보λ₯Ό ν¬ν¨νκ³ μλ 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