line / line-sdk-unity

Provides a modern way of implementing LINE APIs in Unity games, for iOS and Android.
https://developers.line.biz/
Apache License 2.0
117 stars 24 forks source link

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

Closed k0uhe1D closed 10 months ago

k0uhe1D commented 10 months ago

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 https://github.com/line/line-sdk-unity/issues/31

Your environment?

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;
}
k0uhe1D commented 10 months ago

@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;
        }
onevcat commented 10 months ago

@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.

onevcat commented 10 months ago

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

onevcat commented 10 months ago

Fix in the release 1.3.2.