在API中Token的使用方法

Posted 圣叹&北京

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在API中Token的使用方法相关的知识,希望对你有一定的参考价值。

 

最近发现公司接口的验密方式很简单,就是简单的用户名密码校验。客户方面的负责人说要修改一下,所以想起了微信的验证密码的方式故写了这个Demo以供大家学习参考;

 

接口:WebService

 

方式:Token动态加密签名;

 

WebService头参数说明:

 

Signature:加密签名,字符串类型;

Timestamp:当前时间戳,DateTime类型(注意客户端时间和服务端时间差不能大于7秒,可以修改)

Nonce:随机数,字符串类型;

 

参数处理:

 

  1. 客户端用Token+ Timestamp+ Nonce后的字符串进行字典排序;
  2. 客户端将排序后的字符串进行MD5加密;
  3. 将加密后的字符串作为Signature参数传到服务端;

 

 

服务端代码:

/// <summary>

    /// WebService接口 SoapHeader类

    /// </summary>

    public class APISoapHeader : System.Web.Services.Protocols.SoapHeader

    {

        /// <summary>

        ///  加密签名

        /// </summary>

        public string signature { get; set; }

        /// <summary>

        /// 时间戳

        /// </summary>

        public DateTime timestamp{ get; set; }

        /// <summary>

        /// 随机数

        /// </summary>

        public string nonce { get; set; }

    }

 

    /// <summary>

    /// WebService1 的摘要说明

    /// </summary>

    [WebService(Namespace = "http://tempuri.org/")]

    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

    [System.ComponentModel.ToolboxItem(false)]

    // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消注释以下行。

    // [System.Web.Script.Services.ScriptService]

    public class WebService1 : System.Web.Services.WebService

    {

        public APISoapHeader header { get; set; }

 

        [System.Web.Services.Protocols.SoapHeader("header")]

        [WebMethod]

        public string HelloWorld(string msg)

        {

            if (header != null && TokenHelper.TokenVerify(header.signature, header.timestamp, header.nonce))

            {

                return "Hello World:" + msg;

            }

            else

            {

                return "NO";

            }

        }

}

 

 

 

验证代码:

  public abstract class TokenHelper

    {

        /// <summary>

        /// 验证加密签名

        /// </summary>

        /// <param name="header"></param>

        /// <returns></returns>

        public static bool TokenVerify(string signature,DateTime timestamp, string nonce)

        {

 

            bool isok = false;

            if (!string.IsNullOrEmpty(signature)

                && !string.IsNullOrEmpty(nonce))

            {

                TimeSpan ts = DateTime.Now.Subtract(timestamp).Duration();

 

                if (ts.Seconds < 7)//如果请求端时间戳与系统时间差小于7秒则继续验证

                {

                    if (signature.Equals(TokenHelper.GetSignature(timestamp, nonce)))

                    {

                        return true;

                    }

                }

            }

 

            return isok;

        }

        /// <summary>

        /// 获取加密签名

        /// </summary>

        /// <param name="timestamp"></param>

        /// <param name="nonce"></param>

        /// <returns></returns>

        public static string GetSignature(DateTime timestamp, string nonce)

        {

            string token = System.Configuration.ConfigurationManager.AppSettings["APIToken"];

            string str = string.Format("{0}{1}{2}", token, timestamp.ToString(), nonce);

            List<char> str2 = str.ToList<char>();

            str2.Sort();

            string str3 = "";

            foreach (var item in str2)

            {

                str3 = string.Format("{0}{1}", str3, item.ToString());

            }

            return TokenHelper.MD5Encrypt(str3);

        }

        /// <summary>

        /// MD5加密

        /// </summary>

        /// <param name="strText"></param>

        /// <returns></returns>

        public static string MD5Encrypt(string strText)

        {

            string cryptStr = "";

            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();

            byte[] bytes = Encoding.UTF8.GetBytes(strText);

            byte[] cryptBytes = md5.ComputeHash(bytes);

            for (int i = 0; i < cryptBytes.Length; i++)

            {

                cryptStr += cryptBytes[i].ToString("X2");

            }

            return cryptStr;

        }

 

    }

 

测试代码:

 

    class Program

    {

        static void Main(string[] args)

        {

          

 

            string msg = Console.ReadLine();

            ServiceReference1.WebService1SoapClient client = new ServiceReference1.WebService1SoapClient();

 

            ServiceReference1.APISoapHeader header = new ServiceReference1.APISoapHeader();

            Random random = new Random();

            header.timestamp = DateTime.Now;

            header.nonce = random.Next(0, 100).ToString();

            header.signature = TokenHelper.GetSignature(header.timestamp, header.nonce);

            //Thread.Sleep(7000);//如果大于7秒则失败;

            msg = client.HelloWorld(header, msg);

 

 

          

            Console.WriteLine(msg);

 

            Console.ReadKey();

        }

    }

 

 

 

该方法的好处就是传输的密码是随时变化的,而且就算是第三方截获了密码,去根据两个动态值解密也相当困难,而且截获的密码也只能用7秒,7秒后则自动失效;

以上是关于在API中Token的使用方法的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS 中使用 Twitter API 1.1 获取 Token

如何在python中使用github api token进行请求

Clover API 不允许使用商家 api_token 进行连接

在 ASP.NET Core API 中处理 id_token

如何使用 Laravel API 在 AngularJS 表单中发送 csrf_token()?

如何在 Python 中使用 Refresh Token Google API? [复制]