line/line-sdk-unity

Unexpected JSON Format String Returned Instead of JWT String When Using LINE SDK

k0uhe1D opened this issue · 4 comments

Is it a security issue?

No

What did you do?

I tried to obtain the idToken using the LINE SDK.

What did you expect?

Being able to obtain the idToken as a JWT string itself.

What happened actually?

When obtaining the idToken, instead of a JWT string, a converted JSON format string was returned.
In previous versions, a JWT string was returned
#31

Your environment?

  • line-sdk-unity 1.3.1
  • unity 2022.3.13f1
  • Pixel 7 Pro/Android 14

Sample project

private async UniTask<string> GetLineCredential()
{
    string credential = null;
    LineSDK.Instance.Login(new[] { "profile", "openid", "email" }, result =>
    {
        result.Match(
            success =>
            {
                var idTokenRaw = success.AccessToken.IdTokenRaw;
                if (string.IsNullOrEmpty(idTokenRaw))
                {
                    throw new GetCredentialFatalException("scopeに`openid`を含めてください");
                
                var match = Regex.Match(idTokenRaw, @"""rawString"":\s*""([^""]*)""");
                if (match.Success)
                {
                    credential = match.Groups[1].Value;
                }
                else
                {
                    throw new GetCredentialFatalException("idTokenの取得に失敗しました");
                }
            },
            error => throw new GetCredentialFatalException(
                $"LineSDKの認証に失敗しました \n code {error.Code}: {error.Message}"));
    })
    await UniTask.WaitUntil(() => credential != null);
    return credential;
}

@onevcat

It seems that this issue has been fixed only for iOS in PR #63.
Looking at the change differences, I think I will continue to encounter the same problem on Android.

In the following implementation, as advised, I have set the IDTokenNonce, but the same issue continues to occur on Android.

        private async UniTask<string> GetLineCredential()
        {
            string credential = null;
            var loginOption = new LoginOption();
            loginOption.IDTokenNonce = "abc123";
            LineSDK.Instance.Login(new[] { "profile", "openid", "email" }, loginOption, result =>
            {
                result.Match(
                    success =>
                    {
                        var idTokenRaw = success.AccessToken.IdTokenRaw;
                        if (string.IsNullOrEmpty(idTokenRaw))
                        {
                            throw new GetCredentialFatalException("scopeに`openid`を含めてください");
                        }

                        if (ApplicationUtility.UnityAndroid)
                        {
                            var match = Regex.Match(idTokenRaw, @"""rawString"":\s*""([^""]*)""");
                            if (match.Success)
                            {
                                credential = match.Groups[1].Value;
                            }
                            else
                            {
                                throw new GetCredentialFatalException("idTokenの取得に失敗しました");
                            }
                        }
                        else if (ApplicationUtility.UnityiOS)
                        {
                            credential = idTokenRaw;
                        }
                        else
                        {
                            throw new GetCredentialFatalException("未対応のプラットフォームです");
                        }
                    },
                    error => throw new GetCredentialFatalException(
                        $"LineSDKの認証に失敗しました \n code {error.Code}: {error.Message}"));
            });

            await UniTask.WaitUntil(() => credential != null);
            return credential;
        }

@k0uhe1D I tried your code and it seems getting the credential perfectly. Can you try to log and see what is the result of your idTokenRaw on Android?

BTW, it is not intended to be sending a parsed JSON string as idTokenRaw on Android. In our design, it should give you the plain value under the current rawString directly. We will try and see if we can improve this and align the behavior to iOS soon.

Done in #64 and we will prepare a release for it soon.

Fix in the release 1.3.2.