有没有办法检查 oauth 令牌是否过期?

Gau*_*123 7 c# oauth asp.net-web-api

我正在使用 oauth 令牌访问 web api。

令牌在 之后过期1 hour。但我想添加功能以在到期时生成新令牌。

我发现如果令牌过期,它会将 StatusCode 作为unauthorized.

请让我知道它是否是唯一说明令牌到期的状态代码。

van*_*dsh 7

再次复活这篇文章并采用@Lavandysh 的解决方案并加入System.IdentityModel.Tokens.Jwt课堂;调用此方法以了解令牌在请求之前是否仍然有效:

    public bool _isEmptyOrInvalid (string token)
    {
        if (string.IsNullOrEmpty(token))
        {
            return true;
        }

        var jwtToken = new JwtSecurityToken(token);
        return (jwtToken == null) || (jwtToken.ValidFrom > DateTime.UtcNow) || (jwtToken.ValidTo < DateTime.UtcNow);
    }
Run Code Online (Sandbox Code Playgroud)


Pat*_*man 6

最简单的方法是尝试用它调用服务。如果过期了,它会拒绝它,然后你可以申请新的。

您还可以保留收到令牌的时间,并使用 来expires_in计算其大约到期时间。然后,您在过期日期之后发出新请求之前请求新令牌。


Lav*_*ysh 5

我知道这是一个旧帖子,但有一个更直接的方法。如果您从 Base64 格式解码令牌,您可以看到到期日期是什么,然后您可以将其与现在的日期进行比较。

如果你想检查这个方法是否有效,你可以使用这个网站来解码令牌。

现在,在 C# 中,您遇到了一些困难,因为令牌包含 '.' 无法解码,如果您只取出两点之间的中间部分,则长度将变得无效(它应该始终为 4 个)。为了使中间部分具有正确的长度,您可以添加 '=' 符号,直到它是 4 个。

最后,我将日期与当前日期加上一分钟进行比较。因为我不希望将在一秒钟内过期的令牌视为有效。您可能需要调整该时间以适合您的目的。

所以这是我的代码:

    /***
     * Check if the string token is expired by decoding it from the Base64 string
     * Some adjustements to the string are necessairy since C# can only decode certain strings.
     * It cannot handle '.' and requires a string has a length that is a multitude of 4.
     * The information we are interrested in is found between the dots.
     * 
     * The token that is given as a parameter should have approximately the following structure:
     * ddddddddddddddddddddd.ddddddddddddddddddddddddddddddddddddd.dddddddddddddddddddddddddddd
     * And should be a valid Oauth token that may or may not be expired
     */
    public static bool isExpired(String token)
    {
        if (token == null || ("").Equals(token))
        {
            return true;
        }

        /***
         * Make string valid for FromBase64String
         * FromBase64String cannot accept '.' characters and only accepts stringth whose length is a multitude of 4
         * If the string doesn't have the correct length trailing padding '=' characters should be added.
         */
        int indexOfFirstPoint = token.IndexOf('.') + 1;
        String toDecode = token.Substring(indexOfFirstPoint, token.LastIndexOf('.') - indexOfFirstPoint);
        while (toDecode.Length % 4 != 0)
        {
            toDecode += '=';
        }

        //Decode the string
        string decodedString = Encoding.ASCII.GetString(Convert.FromBase64String(toDecode));

        //Get the "exp" part of the string
        String beginning = "\"exp\":\"";
        int startPosition = decodedString.LastIndexOf(beginning) + beginning.Length;
        decodedString = decodedString.Substring(startPosition);
        int endPosition = decodedString.IndexOf("\"");
        decodedString = decodedString.Substring(0, endPosition);
        long timestamp = Convert.ToInt64(decodedString);

        DateTime date = new DateTime(1970, 1, 1).AddMilliseconds(timestamp);
        DateTime compareTo = DateTime.Now.AddMinutes(1);

        int result = DateTime.Compare(date, compareTo);

        return result < 0;
    }
Run Code Online (Sandbox Code Playgroud)


Âng*_*tto 5

我在开发 Xamarin Forms 应用程序时遇到了这个问题。这里的主要问题是我无法在项目中安装任何 Nuget。所以我决定改进@Lavandysg 答案,因为它没有正确提取过期时间戳,也没有正确计算过期时间。这是我使用正则表达式从令牌中提取过期时间的最终代码:

public bool IsTokenExpired(string token)
        {
            if (token == null || ("").Equals(token))
            {
                return true;
            }

            /***
             * Make string valid for FromBase64String
             * FromBase64String cannot accept '.' characters and only accepts stringth whose length is a multitude of 4
             * If the string doesn't have the correct length trailing padding '=' characters should be added.
             */
            int indexOfFirstPoint = token.IndexOf('.') + 1;
            String toDecode = token.Substring(indexOfFirstPoint, token.LastIndexOf('.') - indexOfFirstPoint);
            while (toDecode.Length % 4 != 0)
            {
                toDecode += '=';
            }

            //Decode the string
            string decodedString = Encoding.ASCII.GetString(Convert.FromBase64String(toDecode));

            //Get the "exp" part of the string
            Regex regex = new Regex("(\"exp\":)([0-9]{1,})");
            Match match = regex.Match(decodedString);
            long timestamp = Convert.ToInt64(match.Groups[2].Value);

            DateTime date = new DateTime(1970, 1, 1).AddSeconds(timestamp);
            DateTime compareTo = DateTime.UtcNow;

            int result = DateTime.Compare(date, compareTo);

            return result < 0;
        }
Run Code Online (Sandbox Code Playgroud)