diff --git a/Storage/Storage-Unity/Storage-Unity.csproj b/Storage/Storage-Unity/Storage-Unity.csproj index 5eca288..1151018 100644 --- a/Storage/Storage-Unity/Storage-Unity.csproj +++ b/Storage/Storage-Unity/Storage-Unity.csproj @@ -117,6 +117,12 @@ Internal\Query\LCCompositionalCondition.cs + + LCCaptchaClient.cs + + + LCSMSClient.cs + diff --git a/Storage/Storage.Test/CaptchaTest.cs b/Storage/Storage.Test/CaptchaTest.cs new file mode 100644 index 0000000..773ed3a --- /dev/null +++ b/Storage/Storage.Test/CaptchaTest.cs @@ -0,0 +1,36 @@ +using NUnit.Framework; +using System.Threading.Tasks; +using LeanCloud; +using LeanCloud.Storage; + +using static NUnit.Framework.TestContext; + +namespace Storage.Test { + public class CaptchaTest { + [SetUp] + public void SetUp() { + LCLogger.LogDelegate += Utils.Print; + LCApplication.Initialize(Utils.AppId, Utils.AppKey, Utils.AppServer); + } + + [TearDown] + public void TearDown() { + LCLogger.LogDelegate -= Utils.Print; + } + + //[Test] + public async Task Request() { + LCCapture captcha = await LCCaptchaClient.RequestCaptcha(); + WriteLine($"url: {captcha.Url}"); + WriteLine($"token: {captcha.Token}"); + Assert.NotNull(captcha); + Assert.NotNull(captcha.Url); + Assert.NotNull(captcha.Token); + } + + //[Test] + public async Task Verify() { + await LCCaptchaClient.VerifyCaptcha("on2r", "1TUDkEMu"); + } + } +} diff --git a/Storage/Storage.Test/SMSTest.cs b/Storage/Storage.Test/SMSTest.cs new file mode 100644 index 0000000..cb76dad --- /dev/null +++ b/Storage/Storage.Test/SMSTest.cs @@ -0,0 +1,40 @@ +using NUnit.Framework; +using System.Collections.Generic; +using System.Threading.Tasks; +using LeanCloud; +using LeanCloud.Storage; + +namespace Storage.Test { + public class SMSTest { + [SetUp] + public void SetUp() { + LCLogger.LogDelegate += Utils.Print; + LCApplication.Initialize(Utils.AppId, Utils.AppKey, Utils.AppServer); + } + + [TearDown] + public void TearDown() { + LCLogger.LogDelegate -= Utils.Print; + } + + //[Test] + public async Task RequestSMS() { + await LCSMSClient.RequestSMSCode("15101006007", + template: "test_template", + signature: "flutter-test", + variables: new Dictionary { + { "k1", "v1" } + }); + } + + //[Test] + public async Task RequestVoice() { + await LCSMSClient.RequestVoiceCode("+8615101006007"); + } + + //[Test] + public async Task Verify() { + await LCSMSClient.VerifyMobilePhone("15101006007", ""); + } + } +} diff --git a/Storage/Storage.Test/Utils.cs b/Storage/Storage.Test/Utils.cs index e7e6df2..3876751 100644 --- a/Storage/Storage.Test/Utils.cs +++ b/Storage/Storage.Test/Utils.cs @@ -3,6 +3,10 @@ using LeanCloud; namespace Storage.Test { public static class Utils { + internal const string AppId = "ikGGdRE2YcVOemAaRbgp1xGJ-gzGzoHsz"; + internal const string AppKey = "NUKmuRbdAhg1vrb2wexYo1jo"; + internal const string AppServer = "https://ikggdre2.lc-cn-n1-shared.com"; + internal static void Print(LCLogLevel level, string info) { switch (level) { case LCLogLevel.Debug: diff --git a/Storage/Storage/LCCaptchaClient.cs b/Storage/Storage/LCCaptchaClient.cs new file mode 100644 index 0000000..968c730 --- /dev/null +++ b/Storage/Storage/LCCaptchaClient.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace LeanCloud.Storage { + /// + /// 验证码 + /// + public class LCCapture { + public string Url { + get; set; + } + + public string Token { + get; set; + } + } + + /// + /// 验证码工具类 + /// + public static class LCCaptchaClient { + /// + /// 请求验证码 + /// + /// 验证码图片宽度 + /// 验证码图片高度 + /// + public static async Task RequestCaptcha(int width = 82, + int height = 39) { + string path = "requestCaptcha"; + Dictionary queryParams = new Dictionary { + { "width", width }, + { "height", height } + }; + Dictionary response = await LCApplication.HttpClient.Get>(path, queryParams: queryParams); + return new LCCapture { + Url = response["captcha_url"] as string, + Token = response["captcha_token"] as string + }; + } + + /// + /// 验证 + /// + /// + /// + /// + public static async Task VerifyCaptcha(string code, + string token) { + if (string.IsNullOrEmpty(code)) { + throw new ArgumentNullException(nameof(code)); + } + if (string.IsNullOrEmpty(token)) { + throw new ArgumentNullException(nameof(token)); + } + + string path = "verifyCaptcha"; + Dictionary data = new Dictionary { + { "captcha_code", code }, + { "captcha_token", token } + }; + await LCApplication.HttpClient.Post>(path, data: data); + } + } +} diff --git a/Storage/Storage/LCSMSClient.cs b/Storage/Storage/LCSMSClient.cs new file mode 100644 index 0000000..8688995 --- /dev/null +++ b/Storage/Storage/LCSMSClient.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace LeanCloud.Storage { + /// + /// 短信工具类 + /// + public static class LCSMSClient { + /// + /// 请求短信验证码 + /// + /// + /// + /// + /// + /// + /// + public static async Task RequestSMSCode(string mobile, + string template = null, + string signature = null, + string captchaToken = null, + Dictionary variables = null) { + if (string.IsNullOrEmpty(mobile)) { + throw new ArgumentNullException(nameof(mobile)); + } + + string path = "requestSmsCode"; + Dictionary data = new Dictionary { + { "mobilePhoneNumber", mobile } + }; + if (!string.IsNullOrEmpty(template)) { + data["template"] = template; + } + if (!string.IsNullOrEmpty(signature)) { + data["sign"] = signature; + } + if (!string.IsNullOrEmpty(captchaToken)) { + data["validate_token"] = captchaToken; + } + if (variables != null) { + foreach (KeyValuePair kv in variables) { + data[kv.Key] = kv.Value; + } + } + await LCApplication.HttpClient.Post>(path, data: data); + } + + /// + /// 请求语音验证码 + /// + /// + /// + public static async Task RequestVoiceCode(string mobile) { + string path = "requestSmsCode"; + Dictionary data = new Dictionary { + { "mobilePhoneNumber", mobile }, + { "smsType", "voice" } + }; + await LCApplication.HttpClient.Post>(path, data: data); + } + + /// + /// 验证手机号 + /// + /// + /// + /// + public static async Task VerifyMobilePhone(string mobile, string code) { + string path = $"verifySmsCode/{code}"; + Dictionary data = new Dictionary { + { "mobilePhoneNumber", mobile } + }; + await LCApplication.HttpClient.Post>(path, data: data); + } + } +}