【问题标题】:Is there any way to check if oauth token is expired or not?有什么方法可以检查 oauth 令牌是否过期?
【发布时间】:2016-07-20 21:01:50
【问题描述】:

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

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

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

请让我知道它是否是唯一告诉我令牌过期的状态码。

【问题讨论】:

    标签: c# asp.net-web-api oauth


    【解决方案1】:

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

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

    【讨论】:

    • 当我调用该服务时,它将以哪个状态码拒绝?
    • 它会给出一个HTTP 401, Unauthorized
    • 这将是它在令牌过期时发送的唯一状态码?
    • 通常是这样,是的。 403 用于告诉您在您拥有有效令牌时无权访问它。
    • 这真的取决于实现。 403 应该告诉您您已通过身份验证,但您不允许您请求的资源。 401 只是告诉你你的令牌是错误的,过期/错误/无效/坏。身份验证没有ALMOST 状态。
    【解决方案2】:

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

    如果您想检查此方法是否有效,您可以使用this website 来解码令牌。

    现在,在 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;
        }
    

    【讨论】:

      【解决方案3】:

      再次复活这篇文章并采用@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);
          }
      

      【讨论】:

        【解决方案4】:

        我在开发 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;
                }
        

        【讨论】:

        • 公司安全政策。安装或更新软件包受到限制。
        • 谢谢,让我担心我忽略了一些事情
        • 您的解决方案的问题是 Exp 字符串提取,对我来说,您的解决方案不起作用。其他问题在 DateTime(1970, 1, 1).AddMilliseconds( 行中,过期时间的时间是秒而不是毫秒,所以,只需更改为 AddSeconds。如果你愿意,我可以编辑你的问题并删除我的统一两个答案。你想要吗?
        • 不,谢谢,我很高兴收到建设性的反馈。非常感谢。对我来说,我的代码可能有效,因为服务器部分也是按照协议在内部编写的。所以我想我们的过期时间也只是以毫秒为单位设置的,我稍后会仔细检查。
        • 是的,我确实喜欢这个主意,也提高了可读性。
        猜你喜欢
        • 1970-01-01
        • 2021-12-21
        • 2012-02-03
        • 2018-04-16
        • 1970-01-01
        • 2014-07-23
        • 2023-03-27
        • 1970-01-01
        • 2012-05-23
        相关资源
        最近更新 更多