[LINE]ミニアプリの開発 2

この前の記事

https://qiita.com/syantien/items/ea69f59beac23fe0bd63

# そのまま`userId`はサーバーに渡せない

前回はLIFFのSDKからプロフィール情報を取得するところまでいきました。ここで取得したユーザーIDを使って様々なサーバー処理をしたいところなのですが。そのままユーザーIDをサーバー側に渡すのは危険。そのユーザーじゃなくてもIDを知っている人であればその値を渡すことができて、サーバー側はその人だと信じてしまう。

ということでLINEのドキュメント(下記)では`liff.getIDToken()`で取得したIDトークンをサーバーに送信し、サーバーでIDトークンを検証する（`POST /oauth2/v2.1/verify`）ことで、ユーザーのプロフィール情報を安全に取得できますとあります。

https://developers.line.biz/ja/docs/liff/using-user-profile/#use-user-info-on-server

# liff.getIDTokenでトークンの取得

ということで。下記のようにコードを変更。　`liff.getIDToken()`でトークンを取得してサーバーに渡しています。

```html
 <script>

        liff.init({
            liffId: '{YOUR LIFF ID}',
            withLoginOnExternalBrowser: true,
        }).then(() => {

            liff.getProfile()
                .then((profile) => {
                    $("#profileImage").attr('src', profile.pictureUrl);
                    $("#displayName").text(profile.displayName);
                })
                .catch((err) => {
                    console.log("error", err);
                });

                var token = liff.getIDToken();  // ここでToken取得
                // Load the main page.
　　　　　　　   // Tokenをサーバー側に渡す。
                $("#main").load('{呼びたいURL}?uid=' + token)'); 

        }).catch((err) => {
            alert(err);
        });
    </script>
```

# トークンからユーザー情報を生成する
サーバー側で受け取りUIDを返すためのコードをまず準備。

```csharp
  private async Task<string> GetUidAsync(string uid)
        {
            using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.line.me/oauth2/v2.1/verify"))
            {
                var contentList = new List<string>();
                contentList.Add($"id_token={Uri.EscapeDataString(uid)}");
                contentList.Add($"client_id={Uri.EscapeDataString("{YOUR CLIENT ID}")}");
                request.Content = new StringContent(string.Join("&", contentList));
                request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");

                var response = await _httpClient.SendAsync(request);

                var log = new Dictionary<string, string>();
                log.Add("value2",await response.Content.ReadAsStringAsync());
                _telemetry.TrackEvent("Raw Response Log For Verification API", log);

                var result = JsonConvert.DeserializeObject<LineTokenCheckResponse>(await response.Content.ReadAsStringAsync());

                return result.sub;
            }
        }

  public class LineTokenCheckResponse
        {
            public string iss { get; set; }
            public string sub { get; set; }
            public string aud { get; set; }
            public int exp { get; set; }
            public int iat { get; set; }
            public string nonce { get; set; }
            public string[] amr { get; set; }
            public string name { get; set; }
            public string picture { get; set; }
            public string email { get; set; }
        }
```

ここではsubがユーザーID部分になるので、単純にsubの値を返しています。エラーの時も想定してそのような処理も追加しておいてください。

あとはこの文字クラスを呼べば、サーバー側でも簡単にLineのIdを取得することができます。

# リリースしたアプリ

リリースしたアプリのリリースはこちらになります。

https://receiptroller.com/ja/savetimeandpaper/pr/partners/line-mini-app-release


# 開発仲間募集中

絶賛開発仲間募集しています。 C#の経験あるかた探しています、よろしくおねがいします。興味のある方は下記のお問合せフォームより連絡ください。

https://receiptroller.com/ja/ContactUs