标签:
开篇首先感谢下Dozer同学,他的几篇博文帮助CoderMan省下了很多工作,通过反编译官方的DLLDozer同学二次开发的SDK,我也是丝毫不客气的就拿来直接用了。
那我们就来一步步说一下Asp.net通过Ucenter与Discuz X系列的整合了。
首先搭建自己的网站,在网站目录下建立API文件夹(必须是API文件夹),开始我很疑惑,后来通过查看Discuz的源代码发现了原因,打开uc_server\model\note.php文件找到get_url_code方法,这个方法是每次接口获取远程地址的方法,仔细观察下代码就知道为什么接收页地址父文件夹一定要叫API了:
01 |
function get_url_code($operation, $getdata, $appid)
{ |
02 |
$app = $this->apps[$appid]; |
03 |
$authkey = $app[‘authkey‘]; |
04 |
$url = $app[‘url‘]; |
05 |
$apifilename =
isset($app[‘apifilename‘])
&& $app[‘apifilename‘]
? $app[‘apifilename‘]
: ‘uc.php‘; |
06 |
$action = $this->operations[$operation][1]; |
07 |
$code =
urlencode($this->base->authcode("$action&".($getdata ? "$getdata&" : ‘‘)."time=".$this->base->time, ‘ENCODE‘, $authkey)); |
08 |
|
09 |
return $url."/api/$apifilename?code=$code"; |
10 |
} |
因为Discuz的源代码里面竟然在接收页地址路径前加了API,Coderman认为这样不好,害得很多人调试半天通不了。说了废话一堆,看不下去的朋友肯定自己调试的时候要吃亏了。下面开始步入正题:一、引入SDK,建立接收页
SDK下载地址:https://github.com/dozer47528/UCenter-API-For-DotNet
接下来建立uc.ashx文件如下:
继承SDK中的接口UcApiBase,有如下方法重载:
01 |
public override ApiReturn
DeleteUser(IEnumerable<int>
ids) |
02 |
{ |
03 |
throw new NotImplementedException(); |
04 |
} |
05 |
06 |
public override ApiReturn
RenameUser(int uid, string oldUserName, string newUserName) |
07 |
{ |
08 |
throw new NotImplementedException(); |
09 |
} |
10 |
11 |
public override UcTagReturns
GetTag(string tagName) |
12 |
{ |
13 |
throw new NotImplementedException(); |
14 |
} |
15 |
16 |
public override ApiReturn
SynLogin(int uid) |
17 |
{ |
18 |
throw new NotImplementedException(); |
19 |
} |
20 |
21 |
public override ApiReturn
SynLogout() |
22 |
{ |
23 |
throw new NotImplementedException(); |
24 |
} |
25 |
26 |
public override ApiReturn
UpdatePw(string userName, string passWord) |
27 |
{ |
28 |
throw new NotImplementedException(); |
29 |
} |
30 |
31 |
public override ApiReturn
UpdateBadWords(UcBadWords badWords) |
32 |
{ |
33 |
throw new NotImplementedException(); |
34 |
} |
35 |
36 |
public override ApiReturn
UpdateHosts(UcHosts hosts) |
37 |
{ |
38 |
throw new NotImplementedException(); |
39 |
} |
40 |
41 |
public override ApiReturn
UpdateApps(UcApps apps) |
42 |
{ |
43 |
throw new NotImplementedException(); |
44 |
} |
45 |
46 |
public override ApiReturn
UpdateClient(UcClientSetting client) |
47 |
{ |
48 |
throw new NotImplementedException(); |
49 |
} |
50 |
51 |
public override ApiReturn
UpdateCredit(int uid, int credit, int amount) |
52 |
{ |
53 |
throw new NotImplementedException(); |
54 |
} |
55 |
56 |
public override UcCreditSettingReturns
GetCreditSettings() |
57 |
{ |
58 |
throw new NotImplementedException(); |
59 |
} |
60 |
61 |
public override ApiReturn
GetCredit(int uid, int credit) |
62 |
{ |
63 |
throw new NotImplementedException(); |
64 |
} |
65 |
66 |
public override ApiReturn
UpdateCreditSettings(UcCreditSettings creditSettings) |
67 |
{ |
68 |
throw new NotImplementedException(); |
69 |
} |
其中SynLogin,SynLogout俩个函数就是实现同步登出登录的。
注:如果需要实现写入Session等操作,那不妨像我一样修改下SDK代码,接下来的修改很重要
修改SDK中的UcApiBase文件中的如下方法:
001 |
public void ProcessRequest(HttpContext
context) |
002 |
{ |
003 |
Response
= context.Response; |
004 |
Request
= context.Request; |
005 |
Args
= new UcRequestArguments(Request); |
006 |
if (!check()) return; |
007 |
switchAction(context); |
008 |
} |
009 |
010 |
#region
私有 |
011 |
private HttpResponse
Response { get; set;
} |
012 |
private HttpRequest
Request { get; set;
} |
013 |
private IUcRequestArguments
Args { get; set;
} |
014 |
///
<summary> |
015 |
///
检查合法性 |
016 |
///
</summary> |
017 |
///
<returns></returns> |
018 |
private bool check() |
019 |
{ |
020 |
if (Args.IsInvalidRequest) |
021 |
{ |
022 |
writeEnd("Invalid
Request"); |
023 |
} |
024 |
if (Args.IsAuthracationExpiried) |
025 |
{ |
026 |
writeEnd("Authracation
has expiried"); |
027 |
} |
028 |
return true; |
029 |
} |
030 |
private void writeEnd(string msg) |
031 |
{ |
032 |
Response.Write(msg); |
033 |
Response.End(); |
034 |
} |
035 |
private void writeEnd<T>(UcCollectionReturnBase<T>
msg) |
036 |
where
T : UcItemReturnBase |
037 |
{ |
038 |
writeEnd(msg.ToString()); |
039 |
} |
040 |
private void writeEnd(ApiReturn
result) |
041 |
{ |
042 |
var
msg = result == ApiReturn.Success ? UcConfig.ApiReturnSucceed : UcConfig.ApiReturnFailed; |
043 |
Response.Write(msg); |
044 |
Response.End(); |
045 |
} |
046 |
private void writeForbidden() |
047 |
{ |
048 |
writeEnd(UcConfig.ApiReturnForbidden); |
049 |
} |
050 |
private void switchAction(HttpContext
context) |
051 |
{ |
052 |
if (Args.Action
== UcActions.Test) |
053 |
{ |
054 |
test(); |
055 |
} |
056 |
else if (Args.Action
== UcActions.DeleteUser) |
057 |
{ |
058 |
deleteUser(); |
059 |
} |
060 |
else if (Args.Action
== UcActions.RenameUser) |
061 |
{ |
062 |
renameUser(); |
063 |
} |
064 |
else if (Args.Action
== UcActions.GetTag) |
065 |
{ |
066 |
getTag(); |
067 |
} |
068 |
else if (Args.Action
== UcActions.SynLogin) |
069 |
{ |
070 |
synLogin(context); |
071 |
} |
072 |
else if (Args.Action
== UcActions.SynLogout) |
073 |
{ |
074 |
synLogout(context); |
075 |
} |
076 |
else if (Args.Action
== UcActions.UpdatePw) |
077 |
{ |
078 |
updatePw(); |
079 |
} |
080 |
else if (Args.Action
== UcActions.UpdateBadWords) |
081 |
{ |
082 |
updateBadWords(); |
083 |
} |
084 |
else if (Args.Action
== UcActions.UpdateHosts) |
085 |
{ |
086 |
updateHosts(); |
087 |
} |
088 |
else if (Args.Action
== UcActions.UpdateApps) |
089 |
{ |
090 |
updateApps(); |
091 |
} |
092 |
else if (Args.Action
== UcActions.UpdateClient) |
093 |
{ |
094 |
updateClient(); |
095 |
} |
096 |
else if (Args.Action
== UcActions.UpdateCredit) |
097 |
{ |
098 |
updateCredit(); |
099 |
} |
100 |
else if (Args.Action
== UcActions.GetCreditSettings) |
101 |
{ |
102 |
getCreditSettings(); |
103 |
} |
104 |
else if (Args.Action
== UcActions.GetCredit) |
105 |
{ |
106 |
getCredit(); |
107 |
} |
108 |
else if (Args.Action
== UcActions.UpdateCreditSettings) |
109 |
{ |
110 |
updateCreditSettings(); |
111 |
} |
112 |
} |
将请求上下文传入到方法中,这样我们就可以在uc.ashx写Session了,将SynLogin,SynLogout修改成:
01 |
public override ApiReturn
SynLogin(int uid,
HttpContext context) |
02 |
{ |
03 |
try |
04 |
{ |
05 |
IUcClient
client = new UcClient(); |
06 |
UcUserInfo
user = client.UserInfo(uid); |
07 |
if (user.Success) |
08 |
{ |
09 |
LoggerCore.Debug(user.Uid
+ "--" +
user.UserName); |
10 |
context.Session["uid"]
= user.Uid; |
11 |
context.Session["username"]
= user.UserName; |
12 |
context.Session["email"]
= user.Mail; |
13 |
return ApiReturn.Success; |
14 |
} |
15 |
return ApiReturn.Failed; |
16 |
} |
17 |
catch (Exception
ex) |
18 |
{ |
19 |
LoggerCore.Debug("远程登录错误",
ex); |
20 |
return ApiReturn.Failed; |
21 |
} |
22 |
} |
23 |
24 |
public override ApiReturn
SynLogout(HttpContext context) |
25 |
{ |
26 |
try |
27 |
{ |
28 |
context.Session.Abandon(); |
29 |
} |
30 |
catch (Exception) |
31 |
{ |
32 |
|
33 |
throw; |
34 |
} |
35 |
|
36 |
return ApiReturn.Success; |
37 |
} |
C#部分的代码修改到这里就结束了。
二、配置Ucenter
如下图:
通信密钥的地方大家随便填,生成一段Guid也是可以的。
运行你的Asp.net项目,是不是通信成功了?
Coderman走到这一步蛋蛋差点碎了,因为调试半天都特么的不成功,百思不得其解,查看数据库,调试Discuz的源码,最后发现原来通信配置是通过生成的配置文件缓存读取的,好吧,速度赶紧把Cache删除掉吧,注意有俩处,一处是uc_server文件下的uc_server\data\cache\apps.php,这负责的是Ucenter与第三方应用之间的通信;另外一处是uc_client\data\cache\apps.php,这负责Discuz登录或者其它用户操作通知第三方应用。 至此,通信应该成功了,运行Asp.net代码,在SynLogin方法处打上断点,去Discuz网站前台登录吧,本地LocalHost应该是通信成功了。
三、修改Asp.net的Web.config文件
用于Asp.net程序通知Discuz同步登陆登出,配置如下:
01 |
<appSettings> |
02 |
<!--客户端版本--> |
03 |
<add key="UC_CLIENT_VERSION" value="1.5.2"/> |
04 |
<!--发行时间--> |
05 |
<add key="UC_CLIENT_RELEASE" value="20101001"/> |
06 |
07 |
<!--API
开关(value类型:True False 默认值:True)--> |
08 |
<!--是否允许删除用户--> |
09 |
<add key="API_DELETEUSER" value="True"/> |
10 |
<!--是否允许重命名用户--> |
11 |
<add key="API_RENAMEUSER" value="True"/> |
12 |
<!--是否允许得到标签--> |
13 |
<add key="API_GETTAG" value="True"/> |
14 |
<!--是否允许同步登录--> |
15 |
<add key="API_SYNLOGIN" value="True"/> |
16 |
<!--是否允许同步登出--> |
17 |
<add key="API_SYNLOGOUT" value="True"/> |
18 |
<!--是否允许更改密码--> |
19 |
<add key="API_UPDATEPW" value="True"/> |
20 |
<!--是否允许更新关键字--> |
21 |
<add key="API_UPDATEBADWORDS" value="True"/> |
22 |
<!--是否允许更新域名解析缓存--> |
23 |
<add key="API_UPDATEHOSTS" value="True"/> |
24 |
<!--是否允许更新应用列表--> |
25 |
<add key="API_UPDATEAPPS" value="True"/> |
26 |
<!--是否允许更新客户端缓存--> |
27 |
<add key="API_UPDATECLIENT" value="True"/> |
28 |
<!--是否允许更新用户积分--> |
29 |
<add key="API_UPDATECREDIT" value="True"/> |
30 |
<!--是否允许向UCenter提供积分设置--> |
31 |
<add key="API_GETCREDITSETTINGS" value="True"/> |
32 |
<!--是否允许获取用户的某项积分--> |
33 |
<add key="API_GETCREDIT" value="True"/> |
34 |
<!--是否允许更新应用积分设置--> |
35 |
<add key="API_UPDATECREDITSETTINGS" value="True"/> |
36 |
<!--API
开关结束--> |
37 |
38 |
<!--返回值设置--> |
39 |
<!--返回成功(默认:1)--> |
40 |
<add key="API_RETURN_SUCCEED" value="1"/> |
41 |
<!--返回失败(默认:-1)--> |
42 |
<add key="API_RETURN_FAILED" value="-1"/> |
43 |
<!--返回禁用(默认:-2)--> |
44 |
<add key="API_RETURN_FORBIDDEN" value="-2"/> |
45 |
<!--返回值设置结束--> |
46 |
47 |
<!--[必填]通信密钥--> |
48 |
<add key="UC_KEY" value="xxxxxxxxx"/> |
49 |
<!--[必填]UCenter地址--> |
50 |
<add key="UC_API" value="http://www.xxxxxx.com/uc_server"/> |
51 |
<!--[必填]默认编码--> |
52 |
<add key="UC_CHARSET" value="utf-8"/> |
53 |
<!--[非必填]UCenter
IP--> |
54 |
<add key="UC_IP" value=""/> |
55 |
<!--[必填]应用ID--> |
56 |
<add key="UC_APPID" value="2"/> |
57 |
</appSettings> |
四、发布网站后修改Cookie域
本地好好的同步登录登出放到服务器上确不太灵光了,想了想是不是Cookie域的原因。首先修改Discuz的Cookie域,找到配置文件,修改配置文件:
1 |
$_config[‘cookie‘][‘cookiepre‘]
= ‘hUDo_‘; |
2 |
$_config[‘cookie‘][‘cookiedomain‘]
= ‘.cartrip.cc‘; |
3 |
$_config[‘cookie‘][‘cookiepath‘]
= ‘/‘; |
再来到Asp.net的Web.config添加或者修改cookie域:
1 |
<httpCookies domain=".cartrip.cc"/> |
结束语:再次感谢Dozer的无私奉献,帮大家节省了很多时间和精力,Coderman的俩个网站也已经这样一步步实现了同步登陆和登出,分别是http://www.cartrip.cc和http://piao.cartrip.cc。有朋友认真看完了的话还没有成功的话,那可能是Coderman写的还是不够清楚,那就联系我批斗我吧。
注:文章由CoderMan原创,转载请说明出处:CoderMan官方主页
Asp.net整合Disucuz X 通过Ucenter同步登陆
标签:
原文地址:http://blog.csdn.net/taolinsen/article/details/43226257