开篇首先感谢下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‘ ]; |
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 )); |
09 |
return $url . "/api/$apifilename?code=$code" ; |
因为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) |
03 |
throw new NotImplementedException(); |
06 |
public override ApiReturn
RenameUser( int uid, string oldUserName, string newUserName) |
08 |
throw new NotImplementedException(); |
11 |
public override UcTagReturns
GetTag( string tagName) |
13 |
throw new NotImplementedException(); |
16 |
public override ApiReturn
SynLogin( int uid) |
18 |
throw new NotImplementedException(); |
21 |
public override ApiReturn
SynLogout() |
23 |
throw new NotImplementedException(); |
26 |
public override ApiReturn
UpdatePw( string userName, string passWord) |
28 |
throw new NotImplementedException(); |
31 |
public override ApiReturn
UpdateBadWords(UcBadWords badWords) |
33 |
throw new NotImplementedException(); |
36 |
public override ApiReturn
UpdateHosts(UcHosts hosts) |
38 |
throw new NotImplementedException(); |
41 |
public override ApiReturn
UpdateApps(UcApps apps) |
43 |
throw new NotImplementedException(); |
46 |
public override ApiReturn
UpdateClient(UcClientSetting client) |
48 |
throw new NotImplementedException(); |
51 |
public override ApiReturn
UpdateCredit( int uid, int credit, int amount) |
53 |
throw new NotImplementedException(); |
56 |
public override UcCreditSettingReturns
GetCreditSettings() |
58 |
throw new NotImplementedException(); |
61 |
public override ApiReturn
GetCredit( int uid, int credit) |
63 |
throw new NotImplementedException(); |
66 |
public override ApiReturn
UpdateCreditSettings(UcCreditSettings creditSettings) |
68 |
throw new NotImplementedException(); |
其中SynLogin,SynLogout俩个函数就是实现同步登出登录的。
注:如果需要实现写入Session等操作,那不妨像我一样修改下SDK代码,接下来的修改很重要
修改SDK中的UcApiBase文件中的如下方法:
001 |
public void ProcessRequest(HttpContext
context) |
003 |
Response
= context.Response; |
004 |
Request
= context.Request; |
005 |
Args
= new UcRequestArguments(Request); |
006 |
if (!check()) return ; |
007 |
switchAction(context); |
011 |
private HttpResponse
Response { get ; set ;
} |
012 |
private HttpRequest
Request { get ; set ;
} |
013 |
private IUcRequestArguments
Args { get ; set ;
} |
017 |
///
<returns></returns> |
020 |
if (Args.IsInvalidRequest) |
022 |
writeEnd( "Invalid
Request" ); |
024 |
if (Args.IsAuthracationExpiried) |
026 |
writeEnd( "Authracation
has expiried" ); |
030 |
private void writeEnd( string msg) |
035 |
private void writeEnd<T>(UcCollectionReturnBase<T>
msg) |
036 |
where
T : UcItemReturnBase |
038 |
writeEnd(msg.ToString()); |
040 |
private void writeEnd(ApiReturn
result) |
042 |
var
msg = result == ApiReturn.Success ? UcConfig.ApiReturnSucceed : UcConfig.ApiReturnFailed; |
046 |
private void writeForbidden() |
048 |
writeEnd(UcConfig.ApiReturnForbidden); |
050 |
private void switchAction(HttpContext
context) |
052 |
if (Args.Action
== UcActions.Test) |
056 |
else if (Args.Action
== UcActions.DeleteUser) |
060 |
else if (Args.Action
== UcActions.RenameUser) |
064 |
else if (Args.Action
== UcActions.GetTag) |
068 |
else if (Args.Action
== UcActions.SynLogin) |
072 |
else if (Args.Action
== UcActions.SynLogout) |
076 |
else if (Args.Action
== UcActions.UpdatePw) |
080 |
else if (Args.Action
== UcActions.UpdateBadWords) |
084 |
else if (Args.Action
== UcActions.UpdateHosts) |
088 |
else if (Args.Action
== UcActions.UpdateApps) |
092 |
else if (Args.Action
== UcActions.UpdateClient) |
096 |
else if (Args.Action
== UcActions.UpdateCredit) |
100 |
else if (Args.Action
== UcActions.GetCreditSettings) |
104 |
else if (Args.Action
== UcActions.GetCredit) |
108 |
else if (Args.Action
== UcActions.UpdateCreditSettings) |
110 |
updateCreditSettings(); |
将请求上下文传入到方法中,这样我们就可以在uc.ashx写Session了,将SynLogin,SynLogout修改成:
01 |
public override ApiReturn
SynLogin( int uid,
HttpContext context) |
05 |
IUcClient
client = new UcClient(); |
06 |
UcUserInfo
user = client.UserInfo(uid); |
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; |
15 |
return ApiReturn.Failed; |
19 |
LoggerCore.Debug( "远程登录错误" ,
ex); |
20 |
return ApiReturn.Failed; |
24 |
public override ApiReturn
SynLogout(HttpContext context) |
28 |
context.Session.Abandon(); |
36 |
return ApiReturn.Success; |
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同步登陆登出,配置如下:
03 |
< add key = "UC_CLIENT_VERSION" value = "1.5.2" /> |
05 |
< add key = "UC_CLIENT_RELEASE" value = "20101001" /> |
07 |
<!--API
开关(value类型:True False 默认值:True)--> |
09 |
< add key = "API_DELETEUSER" value = "True" /> |
11 |
< add key = "API_RENAMEUSER" value = "True" /> |
13 |
< add key = "API_GETTAG" value = "True" /> |
15 |
< add key = "API_SYNLOGIN" value = "True" /> |
17 |
< add key = "API_SYNLOGOUT" value = "True" /> |
19 |
< add key = "API_UPDATEPW" value = "True" /> |
21 |
< add key = "API_UPDATEBADWORDS" value = "True" /> |
23 |
< add key = "API_UPDATEHOSTS" value = "True" /> |
25 |
< add key = "API_UPDATEAPPS" value = "True" /> |
27 |
< add key = "API_UPDATECLIENT" value = "True" /> |
29 |
< add key = "API_UPDATECREDIT" value = "True" /> |
30 |
<!--是否允许向UCenter提供积分设置--> |
31 |
< add key = "API_GETCREDITSETTINGS" value = "True" /> |
33 |
< add key = "API_GETCREDIT" value = "True" /> |
35 |
< add key = "API_UPDATECREDITSETTINGS" value = "True" /> |
40 |
< add key = "API_RETURN_SUCCEED" value = "1" /> |
42 |
< add key = "API_RETURN_FAILED" value = "-1" /> |
44 |
< add key = "API_RETURN_FORBIDDEN" value = "-2" /> |
48 |
< add key = "UC_KEY" value = "xxxxxxxxx" /> |
52 |
< add key = "UC_CHARSET" value = "utf-8" /> |
53 |
<!--[非必填]UCenter
IP--> |
54 |
< add key = "UC_IP" value = "" /> |
56 |
< add key = "UC_APPID" value = "2" /> |
四、发布网站后修改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官方主页
时间: 2024-12-16 19:29:33