Upgrade to Pro — share decks privately, control downloads, hide ads and more …

LIFFの説明と裏側の話

 LIFFの説明と裏側の話

LINE Developer Meetup in Kyoto #56で発表したLIFFの説明と裏側の話のスライド。
https://line.connpass.com/event/139283/

Adam Millerchip

July 25, 2019
Tweet

More Decks by Adam Millerchip

Other Decks in Programming

Transcript

  1. ⾃自⼰己紹介 イギリス出身 
 ノーサンプトン市⽣生まれ エディンバラ⼤大学
 Software Engineering 2014年年ワーホリとして来⽇日
 LINE Fukuoka⼊入社


    主にCreators Market
 少しLINE STORE 2018年年2⽉月、LINE Kyoto転勤勤
 Clova CEK SDK (Elixir版)
 LIFF https://www.instagram.com/handluggageonly/
  2. LIFF 1. Use only static resources (HTML, JS, CSS…) Backend不不要

    2. Open your website inside LINE chat 3. Make REST API calls on behalf of the user • Including send messages as user
  3. How does it work? LIFF Thrift API liff id line

    access token Thrift API line access token user id Talk Server REST API user id client id scope rest access token Login Server uri liff id client_id login scopes view metadata
  4. How does it work? LIFF Thrift API liff id line

    access token Thrift API line access token user id Talk Server REST API user id client id scope rest access token Login Server uri liff id client_id login scopes view metadata OAuth2 Browser App Server
  5. How does it work? LIFF url view metatada rest access

    token Thrift API liff id line access token Thrift API line access token user id Talk Server REST API user id client id scope rest access token Login Server uri liff id client_id login scopes view metadata
  6. How does it work? LIFF Talk Server uri liff id

    client_id login scopes view metadata url view metatada rest access token Thrift API liff id line access token REST API user id client id scope rest access token Thrift API line access token user id Login Server https://example.com#access_token=foobarhoge
  7. No consent? LIFF consent required REST API user id client

    id scope consent required Thrift API liff id line access token Login Server
  8. Revoke LIFF Thrift API rest access token REST API rest

    access token Login Server line access token
  9. Kotlin • Originally Java • Now 60% Kotlin, 35% Java

    • All tests are Kotlin • All new files are Kotlin • Convert other files when possible
  10. data class User( val userId: String ) ? @Data class

    User { private String userId; } data class User( val userId: String? = null )
  11. Extensions? data class User( val userId: Optional<String>? ) val userId

    : String? = user.userId?.orElse(null) fun <T> Optional<T>.unwrap(): T? = orElse(null) val userId : String? = user.userId?.unwrap()
  12. public static String getTokenHash(@Nullable String token) { if (token ==

    null) { return null; } try { val messageDigest = MessageDigest.getInstance(SHA256); val fullHash = messageDigest.digest(token.getBytes(StandardCharsets.UTF_8)); return Base64URL.encode(Arrays.copyOf(fullHash, fullHash.length / 2)).toString(); } catch (NoSuchAlgorithmException e) { throw new IllegalStateException("MessageDigest instantiation error", e); } } Extensions (chaining)
  13. public static String getTokenHash(@Nullable String token) { if (token ==

    null) { return null; } try { val messageDigest = MessageDigest.getInstance(SHA256); val fullHash = messageDigest.digest(token.getBytes(StandardCharsets.UTF_8)); return Base64URL.encode(Arrays.copyOf(fullHash, fullHash.length / 2)).toString(); } catch (NoSuchAlgorithmException e) { throw new IllegalStateException("MessageDigest instantiation error", e); } } Extensions (chaining) fun getTokenHash(token: String?): String? = token ?.toByteArray(StandardCharsets.UTF_8) ?.let { MessageDigest.getInstance("SHA-256").digest(it) } ?.let { Base64URL.encode(it.copyOf(it.size / 2)).toString() }
  14. Extensions (no more streams) int sum = 0; for(String string

    : strings) { sum += Integer.valueOf(string); } List<String> strings = Arrays.asList("1", "2", "3"); int sum = strings.stream().mapToInt(Integer::valueOf).sum(); val sum = strings.map(Integer::valueOf).sum()
  15. Call Logging @Pointcut("execution (public * com.linecorp.liff.*(..))") public void liffMethods() {

    } @Slf4j @Aspect public static class LiffLoggingAspect { @Around("liffMethods()") public Object logApiCall(ProceedingJoinPoint pjp) { val info = pjp.getInfo…() Object result = pjp.proceed(); log.info("Call {}.{} took:{}us args:[{}] returns:{} ", ...); return result; } }
  16. TODO • Convert more to Kotlin + use more Kotlin

    features • Implement New Features • Concurrency / Non-Blocking • Improve Logging / Monitoring • Improved Performance Monitoring • ??