目錄
一、前言
二、前期準(zhǔn)備
三、購買短信服務(wù)
四、申請簽名和模板
(1) 進入阿里云短信服務(wù)控制臺
(2) 添加簽名
(3) 添加模板
五、RAM申請及權(quán)限配置
(1) 進入RAM訪問控制界面
(2) 創(chuàng)建用戶
(3) 分配權(quán)限
(4) 創(chuàng)建角色
(5) 記錄關(guān)鍵字段的值
六、阿里云.NET SDK身份驗證接入
(1) 了解身份驗證配置
?(2) 導(dǎo)入.NET SDK
(3) 配置環(huán)境變量
(4) 獲取STSToken的實現(xiàn)
七、代碼發(fā)送短信驗證碼
八、總結(jié)
一、前言
手機登錄在賬號體系中扮演著重要的角色,它不僅是一種方便的身份驗證方式,還有助于提高賬號的安全性和用戶體驗。本篇文章介紹阿里云的短信服務(wù)及代碼發(fā)送短信驗證碼的實現(xiàn)。
二、前期準(zhǔn)備
需要阿里云企業(yè)賬號、一個已經(jīng)備案過的域名(如果沒有我們可以申請測試賬號,一樣可以做到發(fā)送短信,但只能給自己的手機號發(fā))。
阿里云網(wǎng)站:阿里云登錄頁 (aliyun.com)
三、購買短信服務(wù)
先進入短信服務(wù)申請免費或購買短信套餐包。
這里新用戶可以試用免費的套餐包,個人用戶是100條,企業(yè)用戶是200條。
?你們自行操作就好啦,只是一些簡單的支付流程。(略過略過......)
四、申請簽名和模板
先介紹一下簽名和模板是什么。
以阿里云發(fā)來的短信驗證碼為例,【阿里云】就是簽名,也就是我們現(xiàn)在正在申請的簽名。后面的部分為模板,是我們在申請簽名成功后需要申請的。模板中可變的字符為模板參數(shù)(比如說4-6位隨機碼),是在申請模板中進行配置的,后面可以通過代碼動態(tài)給模板參數(shù)賦值。所以只要配置好簽名和模板,我們的短信格式就確定下來啦。
(1) 進入阿里云短信服務(wù)控制臺
我買的短信套餐是國內(nèi)短信,這里選擇國內(nèi)消息。
短信服務(wù) (aliyun.com)
(2) 添加簽名
首先要明確簽名規(guī)范,檢查填寫的內(nèi)容是否合規(guī),提高審核通過率,一次申請審核時長大概在2小時左右。
短信簽名的規(guī)范說明_短信服務(wù)-阿里云幫助中心 (aliyun.com)
下面進行簽名申請:
提交好后等待審核通過就好啦。
(3) 添加模板
模板規(guī)范同理。
短信模板規(guī)范_短信服務(wù)-阿里云幫助中心 (aliyun.com)
?一些模板示例
?等待審核通過即可。
到這里為止,我們需要記錄兩條屬性后續(xù)調(diào)用短信API會用到
- 簽名名稱
- 模板Code
五、RAM申請及權(quán)限配置
先了解一下RAM用戶和RAM角色的概念
什么是RAM用戶?
RAM用戶是RAM的一種實體身份類型,有確定的身份ID和身份憑證,它通常與某個確定的人或應(yīng)用程序一一對應(yīng)。RAM用戶具備以下特點:
- RAM用戶由阿里云賬號(主賬號)或具有管理員權(quán)限的其他RAM用戶、RAM角色創(chuàng)建,創(chuàng)建成功后,歸屬于該阿里云賬號,它不是獨立的阿里云賬號。
- RAM用戶不擁有資源,不能獨立計量計費,由所屬的阿里云賬號統(tǒng)一付費。
- RAM用戶必須在獲得授權(quán)后,才能登錄控制臺或使用API訪問阿里云賬號下的資源。
- RAM用戶擁有獨立的登錄密碼或訪問密鑰。
- 一個阿里云賬號下可以創(chuàng)建多個RAM用戶,對應(yīng)企業(yè)內(nèi)的員工、系統(tǒng)或應(yīng)用程序。
您可以創(chuàng)建RAM用戶并為其授權(quán),實現(xiàn)不同RAM用戶擁有不同資源訪問權(quán)限的目的。當(dāng)您的企業(yè)存在多用戶協(xié)同訪問資源的場景時,使用RAM可以按需為用戶分配最小權(quán)限,避免多用戶共享阿里云賬號密碼或訪問密鑰,從而降低企業(yè)的安全風(fēng)險。
什么是RAM角色?
RAM 角色機制是向您信任的實體(例如:RAM 用戶、某個應(yīng)用或阿里云服務(wù))進行授權(quán)的一種安全方法。根據(jù)不同應(yīng)用場景,受信任的實體可能有如下一些例子:
- 您云賬戶下的一個 RAM 用戶(可能是代表一個移動 App 的后端服務(wù));
- 其他云賬戶中的 RAM 用戶(需要進行跨賬戶的資源訪問);
- ECS 實例上運行的應(yīng)用程序代碼(需要對云資源執(zhí)行操作);
- 某些阿里云服務(wù)(需要對您賬戶中的資源進行操作才能提供服務(wù));
- 企業(yè)的身份提供商 IdP,可以用于角色 SSO。
RAM 角色頒發(fā)短時有效的訪問令牌(STS 令牌),使其成為一種更安全的授予訪問權(quán)限的方法。
特別說明:
RAM 角色不是傳統(tǒng)的權(quán)限集,是一種臨時身份。如果您需要使用權(quán)限集,請前往RAM 權(quán)限策略。
(1) 進入RAM訪問控制界面
RAM 訪問控制 (aliyun.com)
(2) 創(chuàng)建用戶
用戶創(chuàng)建成功后,會得到一個AccessKeyID和AccessKeySecret,這兩個值要保存下來,界面關(guān)閉后AccessKeySecret不再出現(xiàn)。
(3) 分配權(quán)限
這里就是給RAM用戶分配權(quán)限,根據(jù)我們的需要選擇分配,由于我們的功能是短信驗證碼,我們分配以下三種權(quán)限。
- AliyunDysmsFullAccess (管理短信服務(wù)(SMS)的權(quán)限)
- AliyunRAMFullAccess (管理訪問控制(RAM)的權(quán)限,即管理用戶以及授權(quán)的權(quán)限)
- AliyunSTSAssumeRoleAccess (調(diào)用STS服務(wù)AssumeRole接口的權(quán)限)
(4) 創(chuàng)建角色
創(chuàng)建成功啦
(5) 記錄關(guān)鍵字段的值
這里要記下RAM角色的ARN,后面用于調(diào)用AssumeRoleAPI接口的參數(shù)。什么是AssumeRole感興趣的話可以閱讀下面這條鏈接。
調(diào)用AssumeRole獲取扮演該角色的臨時身份_阿里云集成轉(zhuǎn)售解決方案-阿里云幫助中心 (aliyun.com)
我們已經(jīng)創(chuàng)建并配置好了RAM用戶和RAM角色,RAM用戶可以使用自己的訪問密鑰調(diào)用AssumeRole接口,以獲取某個RAM角色的STS Token,實現(xiàn)通過Credentials工具讀取臨時安全令牌(STS Token)用作安全登錄。
到這里我們需要記錄三條重要的字段的值
- RAM用戶的AccessKeyID
- RAM用戶的accessKeySecret
- RAM角色的ARN
六、阿里云.NET SDK身份驗證接入
(1) 了解身份驗證配置
為了更好地理解后續(xù)的代碼,可以先閱讀一下阿里云的身份驗證配置
如何進行Credentials配置(.NETSDK)_阿里云SDK-阿里云幫助中心 (aliyun.com)
?(2) 導(dǎo)入.NET SDK
我選擇的身份驗證方式為官方推薦的環(huán)境變量配置+STS Token,這種方式最為安全和靈活。
首先要先接入相關(guān)SDK,我這里已經(jīng)整理好了所有引用到的dll,開箱即用。
鏈接:https://pan.baidu.com/s/1C4GEYoITqxiyB99Js8zq2g?
提取碼:wvlz?
(3) 配置環(huán)境變量
配置環(huán)境變量的目的是不把重要的AccessKey直接暴露在代碼內(nèi)。
配置環(huán)境變量
ALIBABA_CLOUD_ACCESS_KEY_ID
和ALIBABA_CLOUD_ACCESS_KEY_SECRET
。
Linux和macOS系統(tǒng)配置方法
執(zhí)行以下命令:
export ALIBABA_CLOUD_ACCESS_KEY_ID=<access_key_id> export ALIBABA_CLOUD_ACCESS_KEY_SECRET=<access_key_secret>
<access_key_id>
需替換為已準(zhǔn)備好的AccessKey ID,<access_key_secret>
替換為AccessKey Secret。Windows系統(tǒng)配置方法
新建環(huán)境變量文件,添加環(huán)境變量
ALIBABA_CLOUD_ACCESS_KEY_ID
和ALIBABA_CLOUD_ACCESS_KEY_SECRET
,并寫入已準(zhǔn)備好的AccessKey ID和AccessKey Secret。重啟Windows系統(tǒng)。
(4) 獲取STSToken的實現(xiàn)
直接上代碼
using AlibabaCloud.TeaUtil.Models;
using AlibabaCloud.OpenApiClient.Models;
using AlibabaCloud.SDK.Sts20150401.Models;
using STSClient = AlibabaCloud.SDK.Sts20150401.Client;
using System;/*
? ? STS Token:通過調(diào)用AssumeRole接口扮演角色獲取令牌憑證并調(diào)用openapi,臨時憑證有過期時間,需要用戶更新憑證。
? ? 有權(quán)限的RAM用戶可以使用自己的訪問密鑰調(diào)用AssumeRole接口,以獲取某個RAM角色的STS Token,實現(xiàn)通過Credentials工具讀取臨時安全令牌(STS Token)
? ? 訪問云產(chǎn)品接口。STS Token具有時效性,到期后會自動失效。
? ? 相比于AK硬編碼方式訪問接口,使用STS Token可有效減少因長期訪問AK導(dǎo)致AK泄露的風(fēng)險。
*/
public class STSToken
{
? ? //阿里云賬號下的訪問RAM用戶所需的鑰匙AccessKey,包括keyID和keySecret,這里已經(jīng)配置好環(huán)境變量。
? ? private const string accessKeyID = "ALIBABA_CLOUD_ACCESS_KEY_ID";
? ? private const string accessKeySecret = "ALIBABA_CLOUD_ACCESS_KEY_SECRET";
? ? //sts服務(wù)器地址 參考 https://api.aliyun.com/product/Sts
? ? private const string endPointSTS = "sts.cn-beijing.aliyuncs.com";
? ? private const string regionId = "cn-beijing";
? ? //阿里云RAM角色的Arn
? ? private const string roleArn = "填寫上面的用戶角色Arn";
? ? //Token生效時長/秒,默認(rèn)就是3600,可以改
? ? public const long effectiveDuration = 3600;
? ? private static STSClient CreateClient(string accessKeyId, string accessKeySecret)
? ? {
? ? ? ? Config config = new Config()
? ? ? ? {
? ? ? ? ? ? AccessKeyId = accessKeyId,
? ? ? ? ? ? AccessKeySecret = accessKeySecret,
? ? ? ? ? ? Endpoint = endPointSTS,
? ? ? ? ? ? RegionId = regionId
? ? ? ? };
? ? ? ? return new STSClient(config);
? ? }? ? public static AssumeRoleResponseBody.AssumeRoleResponseBodyCredentials GetAssumeRoleData()
? ? {
? ? ? ? STSClient client = CreateClient(Environment.GetEnvironmentVariable(accessKeyID), Environment.GetEnvironmentVariable(accessKeySecret));
? ? ? ?
? ? ? ? AssumeRoleRequest assumeRoleRequest = new AssumeRoleRequest
? ? ? ? {
? ? ? ? ? ? RoleArn = roleArn,
? ? ? ? ? ? RoleSessionName = "隨便起個名,不可以中文",
? ? ? ? ? ? DurationSeconds = effectiveDuration
? ? ? ? };
? ? ? ? RuntimeOptions runtime = new RuntimeOptions();
? ? ? ? try
? ? ? ? {
? ? ? ? ? ? AssumeRoleResponse arr = client.AssumeRoleWithOptions(assumeRoleRequest, runtime);
? ? ? ? ? ? //返回演員角色數(shù)據(jù),包括keyID keySecret 和Token
? ? ? ? ? ? return arr.Body.Credentials;
? ? ? ? }
? ? ? ? catch (Tea.TeaException error)
? ? ? ? {
? ? ? ? ? // Debug.LogError(error);
? ? ? ? }
? ? ? ? return null;
? ? }
}
七、代碼發(fā)送短信驗證碼
上代碼
using AlibabaCloud.TeaUtil.Models;
using AlibabaCloud.OpenApiClient.Models;
using AlibabaCloud.SDK.Dysmsapi20170525;
using AlibabaCloud.SDK.Sts20150401.Models;
using AlibabaCloud.SDK.Dysmsapi20170525.Models;
using CreConfig = Aliyun.Credentials.Models.Config;
using System;using System.Text.RegularExpressions;
? ? public class SMS
? ? {
? ? ? ? //簽名名稱
? ? ? ? private const string signName = "標(biāo)題四申請的簽名名稱";
? ? ? ? //模板Code
? ? ? ? private const string templateCode = "標(biāo)題四申請的模板Code";
? ? ? ? //短信供應(yīng)商域名
? ? ? ? private const string endpoint = "dysmsapi.aliyuncs.com";
? ? ? ? private const string regionId = "cn-beijing";? ? ? ? /// <summary>
? ? ? ? /// phoneNumbers 可以填多個手機號,以,作為分隔符
? ? ? ? /// </summary>
? ? ? ? /// <param name="phoneNumbers"></param>
? ? ? ? public static void Send(string phoneNumbers)
? ? ? ? {? ? ? ? ? ??//這里先做個正則校驗,手機號是否合規(guī),不合規(guī)拋異常
? ? ? ? ? ? ?if (!IsPhoneNumber(phoneNumbers))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? throw new Exception($"{phoneNumbers}:不合規(guī),請檢查手機號");
? ? ? ? ? ? }
? ? ? ? ? ? Config config = GetConfig();
? ? ? ? ? ? Client client = new Client(config);
? ? ? ? ? ? SendSmsRequest sendSmsRequest = new SendSmsRequest
? ? ? ? ? ? {
? ? ? ? ? ? ? ? SignName = signName,
? ? ? ? ? ? ? ? TemplateCode = templateCode,
? ? ? ? ? ? ? ? PhoneNumbers = phoneNumbers,
? ? ? ? ? ? ? ? TemplateParam = GenerateSMSCode(6)
? ? ? ? ? ? };? ? ? ? ? ? RuntimeOptions runtime = new RuntimeOptions();
? ? ? ? ? ? try
? ? ? ? ? ? {
? ? ? ? ? ? ? ? SendSmsResponse response = client.SendSmsWithOptions(sendSmsRequest, runtime);
? ? ? ? ? ? ? ?//Debug.Log(response.Body.Code);
? ? ? ? ? ? }
? ? ? ? ? ? catch (Tea.TeaException error)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? //Debug.LogError(error.Message);
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? private static DateTime lastGenerateTime;
? ? ? ? private static AssumeRoleResponseBody.AssumeRoleResponseBodyCredentials data;
? ? ? ? private static Config GetConfig()
? ? ? ? {
? ? ? ? ? ? //檢查token是否過期
? ? ? ? ? ? if (data == null || VerifyExpiration(lastGenerateTime, DateTime.Now))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? data = STSToken.GetAssumeRoleData();
? ? ? ? ? ? ? ? lastGenerateTime = DateTime.Now;
? ? ? ? ? ? }
? ? ? ? ? ? if (data == null)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? throw new Exception("Token申請失敗");
? ? ? ? ? ? }? ? ? ? ? ?// Debug.Log(data.SecurityToken);
? ? ? ? ? ? //使用STS創(chuàng)建Config
? ? ? ? ? ? CreConfig creConfig = GetCreConfig(data);
? ? ? ? ? ? Config config = new Config()
? ? ? ? ? ? {
? ? ? ? ? ? ? ? Credential = new Aliyun.Credentials.Client(creConfig),
? ? ? ? ? ? ? ? Endpoint = endpoint,
? ? ? ? ? ? ? ? RegionId = regionId
? ? ? ? ? ? };
? ? ? ? ? ? return config;
? ? ? ? }? ? ? ? private static CreConfig GetCreConfig(AssumeRoleResponseBody.AssumeRoleResponseBodyCredentials data)
? ? ? ? {
? ? ? ? ? ? CreConfig config = new CreConfig
? ? ? ? ? ? {
? ? ? ? ? ? ? ? Type = "sts",
? ? ? ? ? ? ? ? AccessKeyId = data.AccessKeyId,
? ? ? ? ? ? ? ? AccessKeySecret = data.AccessKeySecret,
? ? ? ? ? ? ? ? SecurityToken = data.SecurityToken
? ? ? ? ? ? };
? ? ? ? ? ? return config;
? ? ? ? }????????
? ? ? ? private static bool IsPhoneNumber(string phoneNumbers)
? ? ? ? {
? ? ? ? ? ? string[] phoneNumbersSplit = phoneNumbers.Split(',');
? ? ? ? ? ? for (int i = 0; i < phoneNumbersSplit.Length; i++)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if (!IsMobile(phoneNumbersSplit[i]))
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? return true;
? ? ? ? }? ? ? ? /// <summary>
? ? ? ? /// 驗證手機號碼
? ? ? ? /// </summary>
? ? ? ? /// <param name="mobile"></param>
? ? ? ? /// <returns></returns>
? ? ? ? public static bool IsMobile(string mobile)
? ? ? ? {
? ? ? ? ? ? if (string.IsNullOrEmpty(mobile))
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? return Regex.IsMatch(mobile, @"^(1)\d{10}$");
? ? ? ? }? ? ? ? private static string GenerateSMSCode(int randomCount)
? ? ? ? {
? ? ? ? ? ? // json---->{code:257781}
? ? ? ? ? ? System.Text.StringBuilder sb = new();
? ? ? ? ? ? sb.Append("{");
? ? ? ? ? ? sb.Append("code:");
? ? ? ? ? ? for (int i = 0; i < randomCount; i++)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? sb.Append(UnityEngine.Random.Range(i == 0 ? 1 : 0, 10));
? ? ? ? ? ? }
? ? ? ? ? ? sb.Append("}");
? ? ? ? ? ? return sb.ToString();
? ? ? ? }
? ? ? ? /// <summary>
? ? ? ? /// 是否過期
? ? ? ? /// </summary>
? ? ? ? /// <param name="lastTime"></param>
? ? ? ? /// <param name="currentTime"></param>
? ? ? ? /// <returns></returns>
? ? ? ? private static bool VerifyExpiration(DateTime lastTime, DateTime currentTime)
? ? ? ? {
? ? ? ? ? ? TimeSpan t = currentTime - lastTime;
? ? ? ? ? ? return t.TotalSeconds >= STSToken.effectiveDuration;
? ? ? ? }
? ? }
到這里就結(jié)束啦,只需要調(diào)用Send方法輸入手機號就可以接收到短信驗證碼了,并且緩存了Token,在Token有效期內(nèi)復(fù)用安全又可靠。
最終效果
八、總結(jié)
本篇文章主要講解的是通過阿里云平臺發(fā)送短信驗證碼操作流程,實現(xiàn)了短信驗證碼單條發(fā)送的功能。最主要的身份鑒權(quán)功能已經(jīng)完成,其他功能實現(xiàn)起來非常容易(比如說短信的批量發(fā)送)。文章來源:http://www.zghlxwxcb.cn/news/detail-758450.html
想了解更多短信服務(wù)可以查看阿里云官方相關(guān)文檔,并且官網(wǎng)上提供了代碼測試平臺可以很方便的進行API測試。文章來源地址http://www.zghlxwxcb.cn/news/detail-758450.html
到了這里,關(guān)于【賬號系統(tǒng)之(手機驗證碼登錄)】使用阿里云短信服務(wù),實現(xiàn)服務(wù)商給手機發(fā)送驗證碼功能。的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!