C#開(kāi)發(fā)微信門(mén)戶(hù)及應(yīng)用(41)--基于微信開(kāi)放平臺(tái)的掃碼登錄處理

在現(xiàn)今很多網(wǎng)站里面,都使用了微信開(kāi)放平臺(tái)的掃碼登錄認(rèn)證處理施蜜,這樣做相當(dāng)于把身份認(rèn)證交給較為權(quán)威的第三方進(jìn)行認(rèn)證,在應(yīng)用網(wǎng)站里面可以不需要存儲(chǔ)用戶(hù)的密碼了校辩。本篇介紹如何基于微信開(kāi)放平臺(tái)的掃碼進(jìn)行網(wǎng)站的登陸處理。

1辆童、開(kāi)放平臺(tái)的認(rèn)證

要使用網(wǎng)站的掃碼登錄處理宜咒,就需要先進(jìn)行微信開(kāi)放平臺(tái)帳號(hào)的開(kāi)發(fā)者資質(zhì)認(rèn)證,提交相關(guān)的資料把鉴,以及交付每年300元的認(rèn)證費(fèi)用故黑。



認(rèn)證后,建立相關(guān)的網(wǎng)站應(yīng)用后庭砍,就有相關(guān)的APPID和APPSecret了场晶,這些關(guān)鍵的參數(shù)就可以用來(lái)獲取相關(guān)的用戶(hù)信息了。
網(wǎng)站應(yīng)用的應(yīng)用詳情界面如下所示怠缸。



整個(gè)開(kāi)放平臺(tái)感覺(jué)沒(méi)有多少東西诗轻,不過(guò)需要收費(fèi)認(rèn)證才能使用這些功能,感覺(jué)不是很爽揭北。
我們采用的掃碼登錄扳炬,需要通過(guò)開(kāi)放平臺(tái)獲取用戶(hù)的信息,因此還需要設(shè)置獲取用戶(hù)基本信息接口的域名搔体,否則無(wú)法獲取信息恨樟,從而會(huì)導(dǎo)致重定向出錯(cuò)。

設(shè)置域名在【接口權(quán)限】【網(wǎng)頁(yè)賬號(hào)】【網(wǎng)頁(yè)授權(quán)獲取用戶(hù)基本信息】的修改入口疚俱,如下圖所示劝术。



然后在彈出的對(duì)話(huà)框里面輸入授權(quán)回調(diào)的域名即可。

這樣設(shè)置就可以確保獲取到用戶(hù)信息了计螺。

2夯尽、掃碼登錄的說(shuō)明和具體使用

網(wǎng)站應(yīng)用微信登錄是基于OAuth2.0協(xié)議標(biāo)準(zhǔn)構(gòu)建的微信OAuth2.0授權(quán)登錄系統(tǒng)。
在進(jìn)行微信OAuth2.在進(jìn)行微信OAuth2.0授權(quán)登錄接入之前登馒,在微信開(kāi)放平臺(tái)注冊(cè)開(kāi)發(fā)者帳號(hào),并擁有一個(gè)已審核通過(guò)的網(wǎng)站應(yīng)用咆槽,并獲得相應(yīng)的AppID和AppSecret陈轿,申請(qǐng)微信登錄且通過(guò)審核后,可開(kāi)始接入流程秦忿。
微信OAuth2.0授權(quán)登錄讓微信用戶(hù)使用微信身份安全登錄第三方應(yīng)用或網(wǎng)站麦射,在微信用戶(hù)授權(quán)登錄已接入微信OAuth2.0的第三方應(yīng)用后,第三方可以獲取到用戶(hù)的接口調(diào)用憑證(access_token)灯谣,通過(guò)access_token可以進(jìn)行微信開(kāi)放平臺(tái)授權(quán)關(guān)系接口調(diào)用潜秋,從而可實(shí)現(xiàn)獲取微信用戶(hù)基本開(kāi)放信息和幫助用戶(hù)實(shí)現(xiàn)基礎(chǔ)開(kāi)放功能等。
微信OAuth2.0授權(quán)登錄目前支持authorization_code模式胎许,適用于擁有server端的應(yīng)用授權(quán)峻呛。該模式整體流程為:

  1. 第三方發(fā)起微信授權(quán)登錄請(qǐng)求罗售,微信用戶(hù)允許授權(quán)第三方應(yīng)用后,微信會(huì)拉起應(yīng)用或重定向到第三方網(wǎng)站钩述,并且?guī)鲜跈?quán)臨時(shí)票據(jù)code參數(shù)寨躁;
  2. 通過(guò)code參數(shù)加上AppID和AppSecret等,通過(guò)API換取access_token牙勘;
  3. 通過(guò)access_token進(jìn)行接口調(diào)用职恳,獲取用戶(hù)基本數(shù)據(jù)資源或幫助用戶(hù)實(shí)現(xiàn)基本操作。

獲取access_token時(shí)序圖:


從上圖我們可以大概了解整個(gè)掃碼登陸的處理過(guò)程方面。

3放钦、掃碼登錄的各個(gè)步驟處理

1)用戶(hù)身份的綁定
為了實(shí)現(xiàn)二維碼掃碼登錄,我們需要在現(xiàn)有系統(tǒng)里面綁定用戶(hù)的微信恭金,這樣才能在用戶(hù)掃碼的時(shí)候最筒,判斷用戶(hù)的身份從而實(shí)現(xiàn)自動(dòng)登錄的過(guò)程。
我們可以在用戶(hù)管理里面進(jìn)行統(tǒng)一設(shè)置蔚叨,也可以在常規(guī)用戶(hù)登錄(用戶(hù)名+密碼)后進(jìn)行設(shè)置床蜘,這個(gè)主要看我們是否需要保留用戶(hù)名密碼登陸這種方式。
例如可以在用戶(hù)管理里面統(tǒng)一綁定蔑水,也就是在創(chuàng)建用戶(hù)的時(shí)候邢锯,讓用戶(hù)綁定下微信,獲取微信的唯一標(biāo)識(shí)搀别。


也可以在保留用戶(hù)名密碼的登陸方式外丹擎,讓用戶(hù)登陸系統(tǒng)后自行進(jìn)行綁定微信即可。

上面的界面歇父,就是在一個(gè)頁(yè)面里面彈出一個(gè)層蒂培,然后請(qǐng)求二維碼顯示即可,如下界面代碼所示榜苫。

<div id="divWechat" class="easyui-dialog" style="width:450px;height:350px;padding:10px 20px"
     closed="true" resizable="true" modal="true" iconcls="icon-setting">
    <div>
        <h4>掃描用戶(hù)二維碼护戳,進(jìn)行綁定</h4>
    </div>
    <div align="center">
        <img id="imgQRcode" alt="使用微信掃碼進(jìn)行綁定" style="height:200px;width:auto" />
    </div>

    <div align="right">
        <a href="javascript:void(0)" class="easyui-linkbutton" iconcls="icon-cancel" onclick="javascript: $('#divWechat').dialog('close')">關(guān)閉</a>
    </div>
</div>

上面的層在打開(kāi)的時(shí)候,我們使用JS來(lái)動(dòng)態(tài)獲取二維碼進(jìn)行顯示垂睬,具體JS代碼如下所示媳荒。

//綁定微信登陸
function BindWechat() {
    var url = "http://www.iqidi.com/H5/BindWechat?id=@Session["UserID"]";
    url = encodeURIComponent(url);
    $("#imgQRcode").attr("src", "/H5/QR?url=" + url);
    //打開(kāi)綁定窗口
    $("#divWechat").dialog('open').dialog('setTitle', '使用微信掃碼進(jìn)行綁定');
}

上面的JS只是做前端的數(shù)據(jù)請(qǐng)求和顯示,具體的QR動(dòng)作Action其實(shí)就是生成掃描二維碼的過(guò)程驹饺,這個(gè)二維碼其實(shí)就是采用通用的方式钳枕,來(lái)構(gòu)建一個(gè)指向我們綁定賬號(hào)的地址,從而實(shí)現(xiàn)我們綁定賬號(hào)的判斷赏壹,二維碼的生成過(guò)程如下所示鱼炒。

/// <summary>
/// 轉(zhuǎn)換二維碼連接為圖片格式
/// </summary>
/// <param name="url">二維碼連接</param>
/// <returns></returns>
[HttpGet]
public ActionResult QR(string url)
{
    //初始化二維碼生成工具
    QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();
    qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE;
    qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M;
    qrCodeEncoder.QRCodeVersion = 0;
    qrCodeEncoder.QRCodeScale = 4;

    //將字符串生成二維碼圖片
    var image = qrCodeEncoder.Encode(url, Encoding.Default);
    //保存為PNG到內(nèi)存流  
    MemoryStream ms = new MemoryStream();
    image.Save(ms, ImageFormat.Png);
    image.Dispose();

    return File(ms.ToArray(), "image/Png");
}

為了實(shí)現(xiàn)用戶(hù)的綁定,我們需要獲取當(dāng)前用戶(hù)的身份信息蝌借,因此需要在BindWeChat的操作里面做一個(gè)轉(zhuǎn)向處理昔瞧,如下接口所示指蚁。

/// <summary>
/// 生成綁定微信的地址
/// </summary>
/// <returns></returns>
public ActionResult BindWechat()

這個(gè)函數(shù)處理里面,我們需要重新定向處理硬爆,我們把它定向到BindAccount函數(shù)里面欣舵,方便獲取用戶(hù)的openid和其他必要的信息。
另外我們基于微信開(kāi)放平臺(tái)的應(yīng)用缀磕,建立了一個(gè)和微信賬號(hào)信息的聯(lián)系缘圈,因此創(chuàng)建數(shù)據(jù)庫(kù)信息如下所示。



也就是一個(gè)具體的開(kāi)放平臺(tái)應(yīng)用對(duì)應(yīng)著一個(gè)具體的微信賬號(hào)袜蚕,這樣我們就可以充分利用配置進(jìn)行處理了糟把。
上面提到的BindAccount的處理的邏輯就是獲取必要的信息,然后在數(shù)據(jù)庫(kù)層面對(duì)身份信息進(jìn)行驗(yàn)證牲剃,具體代碼如下所示遣疯。

/// <summary>
/// 綁定用戶(hù)微信號(hào)
/// </summary>
/// <param name="id">賬號(hào)ID</param>
/// <returns></returns>
public ActionResult BindAccount()
{
    WebAppInfo appInfo = GetWebApp(ConfigData.WebAppId);
    AccountInfo accountInfo = GetAccount(appInfo.AccountNo);

    var htResult = GetOpenIdAndUnionId(accountInfo.UniteAppId, accountInfo.UniteAppSecret);//存儲(chǔ)openid方便使用
    string openid = htResult["openid"].ToString();
    var unionid = htResult["unionid"].ToString();
    var userid = Request.QueryString["id"];
    var state = Request.QueryString["state"];

    if (!string.IsNullOrEmpty(openid) && !string.IsNullOrEmpty(userid))
    {
        CommonResult result = BLLFactory<User>.Instance.BindUser(openid, unionid, userid.ToInt32());
        if (result.Success)
        {
            return BindSuccess();
        }
        else
        {
            return BindFail();
        }
    }
    else
    {
        throw new WeixinException("無(wú)法獲取openid" + string.Format(", openid:{0}, userid:{1}", openid, userid));
    }
}

在綁定的過(guò)程,我們需要考慮綁定正確賬號(hào)凿傅,重復(fù)綁定其他賬號(hào)缠犀,無(wú)效綁定幾種情況,如果成功綁定正確賬號(hào)(可多次處理結(jié)果一樣)聪舒,那么得到界面如下所示(這個(gè)界面的樣式采用了weui的樣式)辨液。


2)用戶(hù)的掃碼登錄處理
上面綁定了賬號(hào)后,就可以通過(guò)掃碼進(jìn)行登錄了箱残,掃碼回調(diào)的時(shí)候我們有自己的判斷處理滔迈,掃碼界面如下所示(我們?cè)诒A粲脩?hù)名密碼登陸的方式外,增加了一個(gè)掃碼登錄的處理)被辑。
如果是Bootstrap的界面效果



如果是EasyUI的界面效果



這個(gè)和前面的二維碼顯示規(guī)則差不多燎悍,不過(guò)他們的連接地址是不同的,這個(gè)地方用到了開(kāi)放平臺(tái)的接口盼理,也就是我們前面提到開(kāi)放平臺(tái)認(rèn)證的接口了谈山。
上面的掃碼登錄的界面代碼如下所示。
<!--二維碼掃描登陸的界面層-->
<div id="divWechat" class="easyui-dialog" style="width:550px;height:500px;padding:10px 20px"
     closed="true" resizable="true" modal="true" iconcls="icon-setting">
    <div id="login_container" align="center">
    </div>

    <div align="right">
        <a href="javascript:void(0)" class="easyui-linkbutton" iconcls="icon-cancel" onclick="javascript: $('#divWechat').dialog('close')">關(guān)閉</a>
    </div>
</div>

上面代碼需要引入JS文件榜揖,并使用微信JSSDK的API進(jìn)行顯示的勾哩。

<!--使用微信掃碼進(jìn)行登陸-->
<script src="http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"></script>
<script language="javascript">

    function OpenJSLogin() {
        var obj = new WxLogin({
            id: "login_container",
            appid: "@ViewBag.appid",
            scope: "snsapi_login",
            redirect_uri: "@ViewBag.redirect_uri",
            state: "@ViewBag.state",
            style: "black",
            href: ".impowerBox .qrcode {width: 200px;}"
        });

        //打開(kāi)綁定窗口
        $("#divWechat").dialog('open').dialog('setTitle', '使用微信掃碼進(jìn)行登陸');
    }
</script>

這個(gè)里面的參數(shù),如APPID就是來(lái)源我們認(rèn)證后的開(kāi)放平臺(tái)參數(shù)举哟。

這些信息我們?cè)贛VC控制器后面獲取后綁定在ViewBag,方便界面前端的使用迅矛。

//使用JSLogin登陸
WebAppInfo appInfo = BLLFactory<WebApp>.Instance.FindByID(ConfigData.WebAppId);
ArgumentValidation.CheckForNullReference(appInfo, "Web應(yīng)用程序appInfo");

if (appInfo != null)
{
    ViewBag.appid = appInfo.OpenAppID;
    ViewBag.redirect_uri = appInfo.LoginCallBackUrl;
    ViewBag.state = ConfigData.AuthState;
}

其中的redirect_uri是通過(guò)數(shù)據(jù)庫(kù)獲取的LoginCallBackUrl地址妨猩,這個(gè)地址類(lèi)似如下格式:http://www.iqidi.com/H5/callback?uid=iqidiSoftware
也就是我們?cè)陂_(kāi)放平臺(tái)處理返回后進(jìn)行的回調(diào)處理。
通過(guò)開(kāi)放平臺(tái)的APPID和APPSecret秽褒,我們可以獲取到對(duì)應(yīng)的接口調(diào)用憑證壶硅,然后根據(jù)接口憑證威兜,以及openid,獲得用戶(hù)的公眾平臺(tái)統(tǒng)一的UnionID庐椒,這個(gè)標(biāo)識(shí)是我們用戶(hù)的唯一標(biāo)識(shí)椒舵,代碼如下所示。

var result = baseApi.GetAuthToken(appid, appsecret, code);
if (result != null && !string.IsNullOrEmpty(result.openid))
{
    openid = result.openid;
    var unionResult = baseApi.GetSnsapiUserInfo(result.access_token, result.openid);

    ht.Add("openid", openid);
    ht.Add("unionid", unionResult != null ? unionResult.unionid : "");
}

有了unionid我們就可以根據(jù)這個(gè)標(biāo)識(shí)在我們的用戶(hù)數(shù)據(jù)庫(kù)里面查找對(duì)應(yīng)的用戶(hù)约谈,如下代碼所示笔宿。

//開(kāi)放平臺(tái)的OpenID,不是公眾號(hào)的OpenID,需要轉(zhuǎn)換為unionid
if (!string.IsNullOrEmpty(openid) && !string.IsNullOrEmpty(unionid))
{
    UserInfo userInfo = BLLFactory<User>.Instance.FindByUnionId(unionid);

然后判斷我們?nèi)サ降挠脩?hù)信息是否正確棱诱,如下代碼所示

if (userInfo != null)
{
    CommonResult loginResult = CheckLogin(userInfo.Name);
    if (!loginResult.Success)
    {
        LogHelper.Info(string.Format("用戶(hù)登陸不成功泼橘,{0}", loginResult.ErrorMessage));
    }

    //登陸成功后的重定向地址
    var url = appInfo.HomeUrl;  //例如:http://www.iqidi.com/Home
    return Redirect(url);
}

如果不成功,那么我們定向到指定的界面即可迈勋。

//如不成功炬灭,最后都統(tǒng)一提示信息
ViewBag.Error = "獲取信息失敗,登陸錯(cuò)誤";
return View("LoginError");

如果我們登陸成功后靡菇,需要設(shè)置一些Session信息或者Cookie信息重归,那么就可以通過(guò)CheckLogin函數(shù)進(jìn)行處理即可。
以上就是我們結(jié)合微信開(kāi)放平臺(tái)實(shí)現(xiàn)微信掃碼登錄的過(guò)程厦凤,其中整個(gè)過(guò)程就是用到了下面幾個(gè)過(guò)程鼻吮。
1)使用JSSDK的腳本實(shí)現(xiàn)掃碼獲取code
JS微信登錄主要用途:網(wǎng)站希望用戶(hù)在網(wǎng)站內(nèi)就能完成登錄,無(wú)需跳轉(zhuǎn)到微信域下登錄后再返回泳唠,提升微信登錄的流暢性與成功率狈网。 網(wǎng)站內(nèi)嵌二維碼微信登錄JS實(shí)現(xiàn)辦法:
步驟1:在頁(yè)面中先引入如下JS文件(支持https):

<script src="http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"></script>

步驟2:在需要使用微信登錄的地方實(shí)例以下JS對(duì)象:

var obj = new WxLogin({
  id:"login_container", 
  appid: "", 
  scope: "", 
  redirect_uri: "",
  state: "",
  style: "",
  href: ""
});
  1. 第二步:通過(guò)code獲取access_token
    通過(guò)code獲取access_token

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

3)第三步:通過(guò)access_token調(diào)用接口
獲取access_token后,進(jìn)行接口調(diào)用笨腥,
對(duì)于接口作用域(scope)拓哺,能調(diào)用的接口有以下:


  1. 第二步:通過(guò)code獲取access_token
    通過(guò)code獲取access_token

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

3)第三步:通過(guò)access_token調(diào)用接口
獲取access_token后,進(jìn)行接口調(diào)用脖母,
對(duì)于接口作用域(scope)士鸥,能調(diào)用的接口有以下:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市谆级,隨后出現(xiàn)的幾起案子烤礁,更是在濱河造成了極大的恐慌,老刑警劉巖肥照,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脚仔,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡舆绎,警方通過(guò)查閱死者的電腦和手機(jī)鲤脏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事∨洳ⅲ” “怎么了抹镊?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么称近? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮曹鸠,結(jié)果婚禮上煌茬,老公的妹妹穿的比我還像新娘。我一直安慰自己彻桃,他們只是感情好坛善,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著邻眷,像睡著了一般眠屎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上肆饶,一...
    開(kāi)封第一講書(shū)人閱讀 51,737評(píng)論 1 305
  • 那天改衩,我揣著相機(jī)與錄音,去河邊找鬼驯镊。 笑死葫督,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的板惑。 我是一名探鬼主播橄镜,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼冯乘!你這毒婦竟也來(lái)了洽胶?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤裆馒,失蹤者是張志新(化名)和其女友劉穎姊氓,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體喷好,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡翔横,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了梗搅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片棕孙。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖些膨,靈堂內(nèi)的尸體忽然破棺而出蟀俊,到底是詐尸還是另有隱情,我是刑警寧澤订雾,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布肢预,位于F島的核電站,受9級(jí)特大地震影響洼哎,放射性物質(zhì)發(fā)生泄漏烫映。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一噩峦、第九天 我趴在偏房一處隱蔽的房頂上張望锭沟。 院中可真熱鬧,春花似錦识补、人聲如沸族淮。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)祝辣。三九已至切油,卻和暖如春蝙斜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背澎胡。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工孕荠, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人攻谁。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓稚伍,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親巢株。 傳聞我的和親對(duì)象是個(gè)殘疾皇子槐瑞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容