LINE Engineering
Blog

Spring Security + 設定ファイルで始める LINE との ID Federation

Kazuki MATSUDA 2017.06.12

こんにちは、LINE の事業側で BizDev を担当している、エンジニアの松田です。

LINE Login

LINE は、さまざまなWebサービスがLINEアカウント情報を活用して、サイトに会員登録やログインができる機能、LINE Login を提供しています。 ユーザーが入力したメールアドレス・パスワードの組み合わせを元に LINE 側で認証を行い、API を通じて LINE の userId を提供しています。 Web サービスの開発者の皆様は、取得できた情報を元に『いまアクセスしているユーザーは LINE のユーザー ID = xxx である』ということを確認する事ができます。

この記事では、主として LINE との ログイン連携 (ID Federation・ソーシャルログイン 等とも呼ばれる)に興味のある方向けに、実装の取りかかりの難易度を示すための最低限のコードを紹介します。 他のサービスとログイン連携というと、難しく考えられる場合が多いのですが、LINE Login は業界標準仕様の一つである OAuth 2.0 を利用しており、(いくつかの言語では)ほぼコーディングレスでログイン連携・ユーザー ID の取得が可能です。 今回は Java をサンプルに、Spring が提供している spring-security-oauth2 と設定ファイルの組み合わせでログイン連携処理をしていきたいと思います。 OAuth2 等の技術の仕組みや仕様に関しては触れず、単語自体を知らなくても以降のサンプルを動かすのに問題はありません。 またこの記事では、『OAuth 2.0 でユーザー ID 取得 API 呼び出し認可を受けて、そのアクセストークンを使いユーザー ID を取得できたことをもってユーザー認証とする』ことを、単純に『(OAuth 2.0 を利用した)認証』と表現しています。

サンプルコード

今回 LINE ID 連携に利用する、Spring Security は、DI(Dependency Injection) や Web MVC Framework で有名な Spring Framework のモジュールラインナップの一つです。 OAuth 2.0 仕様に基づくクライアント側実装モジュール spring-security-oauth2 を持っており、これを利用する事で LINE Login と連携することができます。 Spring Boot と組み合わせことで、簡単に Embedded Tomcat サーバーを起動することができ、設定も yaml ファイルから行えますので、こちらも利用しています。 (OAuth 2.0 仕様のクライアント側実装にあたっては、認可サーバーとの往復時に付与される state パラメーターの有無や安全性が重要な要素になります。Spring Security による実装では SecureRandom で生成した state パラメーターを付与しており、意図しない別ユーザーとしてログインさせられてしまうなどの CSRF 攻撃を防いでいます。)

全てのサンプルコードは、https://github.com/line/line-login-sample-for-spring-security からダウンロード頂け、以下のコマンドで試すことができます。

# Maven
% mvn spring-boot:run -Dsecurity.oauth2.client.client-id=<Your Channel ID> -Dsecurity.oauth2.client.client-secret=<Your Channel Secret>
  
# Gradle
% ./gradlew bootRun -Dsecurity.oauth2.client.client-id=<Your Channel ID> -Dsecurity.oauth2.client.client-secret=<Your Channel Secret>

Dependency: pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>line-login-sample</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <properties>
    <java.version>1.8</java.version>
  </properties>
 
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.3.RELEASE</version>
  </parent>
 
  <build>
    <plugins>
      <plugin><!-- mvn spring-boot:run でプロジェクト起動を可能にします -->
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <executions>
          <execution>
            <goals>
              <goal>repackage</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
 
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId><!-- YAML ベースでの spring-security-oauth2 の設定と自動読み込みを可能にします -->
    </dependency>
    <dependency>
      <groupId>org.springframework.security.oauth</groupId>
      <artifactId>spring-security-oauth2</artifactId><!-- LINE Login 連携に必要なライブラリです -->
    </dependency>
  </dependencies>
</project>

Application Code: src/main/com/example/LineLoginApplication.java

package com.example;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
 
@SpringBootApplication
@EnableOAuth2Sso
@RestController
public class LineLoginApplication {
    public static void main(final String... args) throws Exception {
        SpringApplication.run(LineLoginApplication.class, args); // Embedded Tomcat を起動します。
    }
 
    @GetMapping("/")
    public Object whoami(@AuthenticationPrincipal final OAuth2Authentication oAuth2Authentication) {
        return oAuth2Authentication; // 起動した Tomcat の Root Path "/" 認証されたユーザー情報を取得してそのまま返すメソッドです。返値は JSON として返されます。
    }
}

Configuration File: src/main/resources/application.yml

spring-boot-starter-security はここに書かれた情報を元に、ユーザーを LINE のログイン画面に遷移させたり、LINE API を呼び出してユーザー情報を取得します。 この内容を書き換えれば、他の OAuth 2.0 連携プロバイダ(Google や Facebook)と連携する事もできます。
security:
  oauth2:
    client:
      client-id: <Your Channel ID> # business.line.me で発行を受ける OAuth2 Client ID(Channel ID) をココに入力します。
      client-secret: <Your Channel Secret> # Client Secret をココに入力します
      client-authentication-scheme: form # OAuth2 Token Endpoint 呼び出しに使う format です。LINE Login では "FORM" に対応しています。
      user-authorization-uri: https://access.line.me/dialog/oauth/weblogin  # 固定値。ID 連携先のログイン画面です。今回は LINE のログイン画面になります。
      access-token-uri: https://api.line.me/v2/oauth/accessToken # 固定値。認可コードを元に、実際のユーザー情報取得のためのアクセストークンを取得する API の Path です。
    resource:
      user-info-uri: https://api.line.me/v2/profile # 固定値。実際のユーザー情報取得のために提供される API です。2017/05時点では、ユーザーID・ユーザ名・プロフィール画像・ひとことの内容、が取得できます。

LINE Login 側で必要な設定

LINE Login 画面で、Login 後の Callback URL を登録する必要があります。 設定変更しなければ、サーバーホストの URL + /login となり、例えば http://localhost:8080 でアクセスする場合、これは http://localhost:8080/login となります。 これを LINE Login の Technical Configuration → WEB → Callback URL に登録します。

ファイルの配置が終わったら

IDE からであれば、main 文を実行すれば OAuth 2.0 を利用した認証が有効になった状態で Tomcat が起動します。 その状態で http://localhost:8080 にアクセスすると、未ログイン状態ですので、LINE ログイン画面である https://access.line.me/dialog/oauth/weblogin に遷移します。 LINE に登録した E-Mail アドレスとパスワードを入力できれば、http://localhost:8080/ に戻ります。画面上に取得できたユーザー Profile が JSON 形式表示されているはずです。 データの中にはユーザーの表示名やひとことも含まれますが、特に "userId" が、時間経過によって変化しないユーザーの ID になります。

Chrome + JSONView Plugin を利用した場合の表示です。

まとめ

ログイン連携、という言葉からは複雑な連携の仕組みや、大量の実装を想定されるかもしれませんが、公開ライブラリ + 設定ファイルで簡単に連携ができた事がご理解頂けたと思います。LINE は2017/05 時点で、日本国内 6800万 月間アクティブユーザー数を有しており、 ID Federation を提供するプロバイダとして国内で一番人口カバー率の高いプラットフォームになると思います。(日本および各国の最新の状況については、IR 情報 から適時プレゼンテーション資料をご覧下さい。)

Web サービスにおいてはサービスの立ち上がり初期から成長フェーズのどの段階においても、 『どれだけ簡単にアカウントを作れるか』(ユーザー数の増加は順調か) 『どれだけ多くのユーザーがパスワードを忘れること無く、サービスに定期的に戻ってきてくれるか』(リテンション・アクティブユーザー率は適正か) などが問われると思います。LINE Login によって既にユーザーがアカウントを作成している LINE に認証を委譲するのは、上記の解決策になるかと思います。

LINE Login Platform に限らないことですが、ID Federation を実施する事で、サービス開発者の皆様は本来のサービスに集中することができ、ユーザーから見ると管理するパスワードが少なくなりそれを集中的に管理すればいいという、ユーザー・開発者の皆様にとってより Web サービスが使いやすい状態を目指せればと思います。

LINE O2O事業室では、新規事業のアライアンスから、サービスやコンテンツの企画・運営、グロースハックに近い微修正まで、様々な各種バックグラウンドを持ったメンバーがそれぞれの形でサービスに携わっています。もし興味があれば LINE 採用情報 のページからまずはエントリーしてみて下さい。

LINE Login

Kazuki MATSUDA 2017.06.12

Add this entry to Hatena bookmark

リストへ戻る