mvc3和dz nt v3.6完美跨域登陸整合解析


 

一、關於dz nt,我要說!

         最近由於工作需要,開發了一套企業內網管理系統。領導想要加上一個論壇,自己做工期太長,況且做出來的也不一定比得上市面上成熟的一些論壇產品(國內如風訊,動網,dz等)。So領導決定采用dz nt v3.60整合到現有企業內網管理系統中,何況 dz nt v3.60剛開源。理論上講雖然沒做過,但有源碼好像怎么整合沒問題。也許是這樣的,往往理想很豐滿,現實很骨感!

   對於 dz nt我真不知道怎么說,要形容的話,用“雞肋”吧!或許更貼切些,nt版本感覺完全是在照顧MS的面子,性能不如PHP(不過也是,康盛主打產品就不是nt.),官方論壇沒有提供相關服務。不說其他,單說那些OpenAPI(快要崩潰掉,什么BT API啊。。。。),官方提供的示例源碼我看了三遍愣是沒完全看懂嘛意思,怎么用(說到這真是崩潰,不知道是我智商低還是,唉那不說了,我知道園內有康盛的大牛。)?還有官方論壇提供的那些所謂的“萬能,深度,跨域”整合,全是胡鬧(我基本都測試了)。好了,或許我說他不好,不能代表他不好。大家請看:

官方API鏈接:http://nt.discuz.net/showtopic-142924.html

用戶創建對話:image

好吧,不再牢騷了,言歸正傳。說這么多,我更想說的是:

  1. OpenAPI應該是簡潔明了,那怕你沒有相關文檔,你也能讓調用他的人明白這個方法是干什么的,我怎么用,需要傳那些參數?
  2. OpenAPI應該是描述調用環境和提供測試DEMO的。

   以上不是不是本文的重點,重點在下面。

二、dz nt 跨域完美整合

  1. 背景:企業內網管理系統(A)+dz nt v3.60(B)跨域整合,實現由A到B自動登陸,注冊,退出,修改等功能。由B到A自動登陸,用戶可以單獨登陸A系統或者B論壇。
  2. 整合思路:

             2.1 通過UCenter來整合第三方應用程序和康盛的其他產品,如圖:

     image

    關於此方案,一方面工期原因,一方面運行環境要求(UCenter需要運行mysql數據庫,我們服務器不允許裝,而且整個整合方案需要配置,開發周期也會比較長),所以我們最終放棄此方案。不過,我見過成功的案例(鄭州打折網),整合了自己開發的應用程序,dz X系列論壇和新浪微薄。若有感興趣的同學可以自己試下,網上有不少相關資料見此博客,官方亦提供不少相關資料。

       2.2 cookie驗證

    說到這里,不得不提下dz nt的驗證機制,他是基於cookie來判斷的,使用論壇后台登錄和前台並行確認機制,您必須正確登錄前台后才可以訪問后台並進行登錄操作。

image 

    所以我的整合思路是,其一在A程序里模擬寫入cookie通過超鏈接自動跳轉論壇登陸。其二在B論壇中新增跳轉頁面,從A程序里傳入必要參數到B論壇跳轉頁面,在page_load中寫入cookie通過驗證,自動登陸論壇。

  dz nt安裝有三種方式,因為不同的安裝方式在寫cookie的時候會有些不同。

     dz nt安裝方式有三種http://nt.discuz.net/showtopic-128292.html

1.根目錄安裝
      根目錄安裝是最簡單也是穩定系數最高的安裝和使用方式,為我們的推薦方式。論壇配置項不需要做任何調整,只需要將站點程序(安裝包upload_files目錄內的所有文件)上傳至站點根目錄下就可以運行install/index.aspx開始安裝了。

2.虛擬目錄安裝
       由於Discuz!NT擁有能大幅優化搜索引擎友好度的頁面偽靜態功能,所以如果論壇程序不是安裝在根目錄下,那么進行安裝過程之前將不得不手工的修改論壇的配置節點以適應虛擬目錄路徑。

打開DNT.config,將<forumpath>/</forumpath>修改為<forumpath>/[您的虛擬目錄名稱]/</forumpath>
然后就可以運行install/index.aspx開始安裝了。

3.子目錄安裝
      因為很多站點是將論壇整合到自己的站點,但是因為某種原因,不能以虛擬目錄的形式存在,則將論壇程序放置在主站點的目錄下,稱為子目錄。

官方有詳細的圖文教程,怎么安裝我不在細說,我只講下我通過這三種方式的一些教訓。

講之前我先介紹下配置環境:

環境:A系統是做負載均衡,B論壇沒有做,WIN2008+IIS7.5+MVC3(即A系統)+MSSQL2008。

    以上是我們的整合環境,第一種根目錄安裝也是我最終采用的方式。虛擬目錄安裝和子目錄安裝總會出現各種各樣的問題,時間緊迫也沒有追根溯源。比如:在虛擬目錄下配置后,運行出錯,必須要建應用程序?在子目錄下安裝,運行后只在論壇首頁,其他鏈接無效?如果以上那位同學做過類似配置或知其原因,請留言告知,非常感謝!

最后我們采用的根目錄安裝配合子域名發布,如A程序的域名為www.a.com,那B論壇的域名為www.bbs.a.com。論壇安裝后好,需要登陸論壇在后台——擴展添加相應整合的程序的一些配置,官方有教程,不細說。

  •    2.2.1 接下去如第一種cookie驗證思路,在A程序中模擬寫入cookie,進行校驗。這種思路驗證時遇到一個問題,從A程序跳轉到B論壇總是跳轉不過去,不能自動登陸。這個問題困擾我好幾天,最后才弄清問題原因在Domain,A系統的域是a.com,B論壇的域是bbs.a.com,就是cookie在二級域名可以寫到一級域名中,一級域名卻不能寫到二級域名中,簡單說父域名不能寫到子域名中。這樣就造成了,論壇在驗證時我A系統跳轉到論壇時所取的cookie Domain就不一樣,根本通不過校驗。如果兩個應用程序要進行雙向自動登陸跳轉,必須保證:
    1. 持共用用戶庫
    2. 驗證機制一樣
    3. 驗證內容一樣
    4. 驗證同一來源,要從一個domian中取cookie來驗證。

所以,由於論壇域名是A系統子域名,我要在論壇登陸時改變其cookie域和A系統一樣,並且保存cookie方法一致,內容一樣才可以。

雖然有源碼。但是,要我在短短幾天理解透徹dz nt的整個驗證機制及登陸過程並修改,難度不小,特別是遇到dz nt那BT的模版機制,更讓人抓狂。如圖:

image

 

 

 

 

 

截取其中片斷。而且就算我理解了他的驗證機制,模版機制和登陸過程,我還要在A系統中模擬Cookie寫入,雖然有接口,但需要模擬環境。總是不是少引用,就是方法有問題,整個一個亂字了得!所以,我放棄,采用第二cookie驗證思路。

  • 2.2.2 采用在B論壇中增加跳轉頁面,從A系統傳入參數,在跳轉頁面寫入Cookie進行驗證登陸。用論壇現有的環境,論壇現有的方法,不需要再重新搭建。只需要幾行代碼搞定MVC3應用程序與論壇完美整合。因為是牽涉到公司項目,不便提供源碼,敬請見諒!以下是核心代碼:

B論壇中

   1:  using System;
   2:  using System.Collections;
   3:  using System.Configuration;
   4:  using System.Data;
   5:  using System.Web;
   6:  using System.Web.Security;
   7:  using System.Web.UI;
   8:  using System.Web.UI.HtmlControls;
   9:  using System.Web.UI.WebControls;
  10:  using System.Web.UI.WebControls.WebParts;
  11:  using System.Security.Cryptography;
  12:  using System.IO;
  13:   
  14:  using Discuz.Common;
  15:  using Discuz.Forum;
  16:  using Discuz.Config;
  17:  using Discuz.Entity;
  18:  using System.Text;
  19:   
  20:   protected void Page_Load(object sender, EventArgs e)
  21:          {
  22:              string username = string.Empty;
  23:              string pwd = string.Empty;
  24:              if (Request.QueryString["un"] != null)
  25:                  username = decode(Request.QueryString["UN"].ToString());//加密后的用戶名
  26:              if (Request.QueryString["pwd"] != null)
  27:                  pwd = decode(Request.QueryString["pwd"].ToString());//加密后的密碼
  28:              try
  29:              {
  30:                  Discuz.Config.GeneralConfigInfo config = Discuz.Config.GeneralConfigs.GetConfig();
  31:                  int uid = Users.GetUserId(username);
  32:                  if (uid == -1)
  33:                  {
  34:                      Response.Redirect("Http://www.XXXX.com");
  35:                      return;
  36:                  }
  37:   
  38:                  //刪除之前的錯誤登錄信息
  39:                  LoginLogs.DeleteLoginLog(DNTRequest.GetIP());
  40:                  //根據積分公式刷新用戶總積分
  41:                  UserCredits.UpdateUserCredits(uid);
  42:                  //寫入用戶登錄后的cookie
  43:                  ForumUtils.WriteUserCookie(uid, Utils.StrToInt(DNTRequest.GetString("expires"), -1), config.Passwordkey, DNTRequest.GetInt("templateid", 0), DNTRequest.GetInt("loginmode", -1));
  44:                  //更新用戶最后動作,如不需要可不執行
  45:                  //OnlineUsers.UpdateAction(olid, UserAction.Login.ActionID, 0, config.Onlinetimeout);
  46:                  //更新該用戶最后訪問時間
  47:                  Users.UpdateUserCreditsAndVisit(uid, DNTRequest.GetIP());
  48:                  Response.Redirect("index.aspx");
  49:              }
  50:              catch(Exception ex)
  51:              {
  52:                  throw ex;
  53:              }
  54:   
  55:          }
  56:          //字符串加密   
  57:          private static string encode(string strText)
  58:          {
  59:              Byte[] Iv64 = { 11, 22, 33, 44, 55, 66, 77, 88 };
  60:              Byte[] byKey64 = { 10, 20, 30, 40, 50, 60, 70, 80 };
  61:              try
  62:              {
  63:                  DESCryptoServiceProvider des = new DESCryptoServiceProvider();
  64:                  Byte[] inputByteArray = Encoding.UTF8.GetBytes(strText);
  65:                  MemoryStream ms = new MemoryStream();
  66:                  CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(byKey64, Iv64), CryptoStreamMode.Write);
  67:                  cs.Write(inputByteArray, 0, inputByteArray.Length);
  68:                  cs.FlushFinalBlock();
  69:                  return Convert.ToBase64String(ms.ToArray());
  70:              }
  71:              catch (Exception ex)
  72:              {
  73:                  return ex.Message;
  74:              }
  75:          }
  76:          //字符串解密   
  77:          private static string decode(string strText)
  78:          {
  79:              Byte[] Iv64 = { 11, 22, 33, 44, 55, 66, 77, 88 };
  80:              Byte[] byKey64 = { 10, 20, 30, 40, 50, 60, 70, 80 };
  81:              Byte[] inputByteArray = new byte[strText.Length];
  82:              try
  83:              {
  84:                  DESCryptoServiceProvider des = new DESCryptoServiceProvider();
  85:                  inputByteArray = Convert.FromBase64String(strText);
  86:                  MemoryStream ms = new MemoryStream();
  87:                  CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(byKey64, Iv64), CryptoStreamMode.Write);
  88:                  cs.Write(inputByteArray, 0, inputByteArray.Length);
  89:                  cs.FlushFinalBlock();
  90:                  System.Text.Encoding encoding = System.Text.Encoding.UTF8;
  91:                  return encoding.GetString(ms.ToArray());
  92:              }
  93:              catch (Exception ex)
  94:              {
  95:                  return ex.Message;
  96:              }
  97:          }

A程序中,就是通過URL傳參就可以了.

修改時間:2012-2-11,以上整合dz nt 版本為Discuz!NT 3.6.711!

三、結束  至此,MVC3應用程序和dz nt論壇完美整合,跨域訪問結束,如果本文對您有幫助,或您有其他想法請留言,交流!

打個廣告:Thinkeer 網是一個IT 技術類相關資料分享的專業網站,致力於打造一個“自由,分享,交流”的技術平台,供程序員學習,交流!
使命:I Can Help You!

PS:本文由於個人技術經驗有限,若有紕漏或錯誤之處敬請諒解。分享(Share),自由(Free),交流(Communicate)的學術氛圍,技術才能得以提升!

作   者:lonely_rain
出   處:http://www.cnblogs.com/lonely_rain/
個人站:  http://www.thinkeer.com/
歡迎任何形式的轉載,但請務必注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM