java J2EE与DiscuzX3.2的UCenter实现单点登录
最近笔者在实现Java项目对discuz的整合。在此过程中,查了很多这方面的资料,发现网上并没有说得比较全面的文章。笔者博取众长以及自己在此过程中遇到的问题,写下来供大家参考,希望大家可以在这过程中少走弯路。笔者在此过程中主要参考了https://code.google.com/p/discuz-ucenter-api-for-java/后,感谢作者ping china.大家可以到此下载接口。
第一步:写好你的配置文件config.properties。(把这个文件放J2EE工程的源路径下就行)
UC_API = http://你的discuz地址/uc_server 如http://10.238.11.11/forum/uc_server
UC_IP = 正常情况下留空即可
UC_KEY = 123456(与ucenter通信的密钥,这里自己设定,需与discuz ucenter一支)
UC_APPID = 2
UC_CONNECT = 正常情况下留空即可
第二步:在你的web.xml里加上
- <!-- servlet 'disuz_uc_api' 用于接收Discuz UCenter的同步消息, 此项配置必须有。(可适当调整 load-on-startup参数) -->
- <servlet>
- <servlet-name>disuz_uc_api</servlet-name>
- <servlet-class>com.fivestars.interfaces.bbs.api.UC</servlet-class>
- <load-on-startup>2</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>disuz_uc_api</servlet-name>
- <url-pattern>/api/uc.php</url-pattern>
- </servlet-mapping>
<servlet-class>com.fivestars.interfaces.bbs.api.UC</servlet-class>如果是直接把使用的UC类放在自已的项目中类包名应该根据自已的包名修改。
<url-pattern>/api/uc.PHP</url-pattern>(这里一定要配置成/api/加上Ucenter中的接口文件名一样,如果J2EE项目中用了权限控制工具如shiro,记得把你的/api/uc.php开放成无需登录也能访问的url)
第三步:配置ucenter.
以管理员身份登录-》管理中心-》ucenter-》应用管理。
填写以下信息:应用名称:你的应用的名称
通信密钥:你刚在config.properties的UC_KEY (123456)
是否开启同步登录:是
是否接受通知:是
其他的留空即可。
如下图所示:
如果出现以下情形,则Ucenter与J2EE项目联接完成:
通信不成功记得查看你的权限的问题,查看http://ip:<port>/{project}/api/uc.php是否未登录可以访问,因为我们的项目中用了shiro对权限进行控制
http://ip:<port>/{project}/api/uc.php未登录是不能访问的,一直通信失败也是找了好久才找到错误的原因。
下面是J2EE对Discuz的同步登录测试:(如果在要测试这一步,只需要把以上第一步和第二步完成后就可以测试,不用Ucenter与J2EE通信成功)
然后我们先试一下登录,以下是测试代码。(到这里还不支持中文,后面会提到)
首先要将里的源代码或者jar导入J2EE项目中。如果不能FQ的朋友请到这里下载:《discuz_ucenter_api_for_java.zip》解压后把以下目录的中的全部java源代码放在自己的项目中就行但要注意,上面web.xml中配置的<servlet-class>com.fivestars.interfaces.bbs.api.UC</servlet-class> 要与这里导入包一致。
然后就可以java代码就调用以下的方法就可以完成功能了:
- public static String login(String userName,String pwd){
- Client e = new Client();
- String result = e.uc_user_login(userName, pwd);
- String $ucsynlogin = "";
- LinkedList<String> rs = XMLHelper.uc_unserialize(result);
- if(rs.size()>0){
- int $uid = Integer.parseInt(rs.get(0));
- String $username = rs.get(1);
- String $password = rs.get(2);
- String $email = rs.get(3);
- if($uid > 0) {
- $ucsynlogin = e.uc_user_synlogin($uid);
- } else if($uid == -1) {
- System.out.println("用户不存在,或者被删除");
- } else if($uid == -2) {
- System.out.println("密码错");
- } else {
- System.out.println("未定义");
- }
- }else{
- System.out.println("Login failed");
- System.out.println(result);
- }
- return $ucsynlogin;
- }
建一个测试类,把这个方法加进去,然后调用此方法,传参数值用户名和密码,然后返回的是一个string。string的内容是一段js代码。
js代码如下:
<script type="text/JavaScript" src="http://10.238.18.80:8181/api/uc.php?time=1456454359&code=21a8EQSq6G3mCzbecik4DxlsNWfm0icW44qGLPgcnC2N5QyPfu0EtDpkZJ8xMjFSWVhOwJhxwBJCuCDOFTL6YWkYQgelDp5OzqGmqNpJ3CVqw2Eh4xm2IOO2uoVDzxBFWlXGmTWRAamNmHzPbiylTg6fXnvcRA9T0ihk" reload="1"></script>
只要把这段js代码输出到页面上去就实现了discuz那边的登录了。你可以先试试把这段js输入到浏览器的地址栏。只要把红色的url复杂到浏览器访问,然后访问Discuz的首页就可以看到相应的用户已经登录了。(下面包括注册以及登出啊,原理都是一样,只要创建Client对象,并且对其调用相对应的方法就行)
退出测试代码:
- public static String logout(){
- Client uc = new Client();
- String $ucsynlogout = uc.uc_user_synlogout();
- System.out.println("退出成功"+$ucsynlogout);
- return $ucsynlogout;
- }
此方法也是返回一段js。输出页面即可,测试时可以先在浏览器地址栏输入。
注册测试代码:
- public static void reg(String userName, String password, String email) {
- Client uc = new Client();
- String $returns = uc.uc_user_register(userName, password ,email);
- int $uid = Integer.parseInt($returns);
- if($uid <= 0) {
- if($uid == -1) {
- System.out.print("用户名不合法");
- } else if($uid == -2) {
- System.out.print("包含要允许注册的词语");
- } else if($uid == -3) {
- System.out.print("用户名已经存在");
- } else if($uid == -4) {
- System.out.print("Email 格式有误");
- } else if($uid == -5) {
- System.out.print("Email 不允许注册");
- } else if($uid == -6) {
- System.out.print("该 Email 已经被注册");
- } else {
- System.out.print("未定义");
- }
- } else {
- System.out.println("OK:------------------------"+$returns);
- }
- }
到这里,还只是实现了java项目登录后论坛那边能自动登录。但论坛那边登录了,java这边还没登录。
因为我们本身的系统的用户名只能是手机号码,所以关于中文的问题没有测试过,这里复制过来,也只是为了整个问题解决方案的完整性。有需要的朋友自行测试。
别急,我们先解决一下中文用户名的问题,其实这个问题https://code.google.com/p/discuz-ucenter-api-for-java/里已经提到了,并提供了解决方案。感谢原作者。但我还是啰嗦一下,因为我感觉说的不够详细,大家可能要花去你的宝贵时间去了解。解决方法如下:
在PHPFuctions.java里有一个名叫urlencode的方法。
只要用以下方法重载一下就好
- protected String urlencode(String value,String code){
- try {
- return URLEncoder.encode(value,code);
- } catch (UnsupportedEncodingException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return null;
- }
并把Client.java里的uc_api_input方法改成如下
- public String uc_api_input(String $data) {
- String $s = urlencode(uc_authcode($data+"&agent="+md5("")+"&time="+time(), "ENCODE" , UC_KEY),"GBK");
- return $s;
- }
好!java中文登录问题解决了。
下面是Discuz那边登录,J2EE方面也登录的解决方法,这里就需要前面做换Ucenter和J2EE的通信成功才能完成以下测试了:
我们来看看discuz那边登录了,java这边怎么实现同步登录。
在UC.java里有一个doanswer的方法。所有同步操作都在这个方法里完成。
其逻辑是这样的,UC这个类继承了HttpServlet。
当ucenter发出通知时,会访问这个servlet.并执行他的doGet()方法。doGet()调用doAnswer().
String $code = request.getParameter("code");
会传一个code进来(加密了的)。
然后调用$code = new Client().uc_authcode($code, "DECODE");进行解密操作。
新建一个Map,Map<String,String> $get = new HashMap<String, String>();
然后根据解密出来的code的内容封装这个Map.
调用这个方法,parse_str($code, $get); 经过以上操作后,所有同步操作需要的信息都在map里,如action。
action代表的是什么操作,如同步登录,同步退出,修改密码等。还有其他信息,如username.登录的用户名。
改密码时还会传新密码过来。所有的这些都包含在这个叫$get的Map里。然后我们就可以进行我们自己的逻辑操作了。
(以上逻辑不想理解没关系,你只要知道当你在discuz登录之后,uc.java的doAnswer()方法就会被调用,你所需要的一切信息都包含在$get这个Map里)
操作到这里,你一定想吐槽笔者!不行啊,discuz那边登录了,java这边完全没反应啊!!doAnswer方法没有被调用啊!是的,你还需要到discuz后台做一些设置。
管理中心->站长->ucenter设置。把ucenter连接方式改为接口方式。然后,你登录discuz时,doAnswer()方法就会被调用了。(其他操作如退出也一样)
到这里,我们又遇到了中文的问题了,discuz用中文登录的时候不行啊!是的,这确实是个比较麻烦的问题。
笔者也弄了好久。原因是这样的:
上面提到过,传进来的$code是需要uc_authcode()方法进行解密的,当中文的时候解密出来的$code是"".解决方法如下:在Client.java的uc_authcode()方法里找到这句String $result = $result1.substring(0, $result1.length());
并把它改成:
- String $result= $result1.toString();
- try{
- $result=new String($result.getBytes("iso-8859-1"),"GBK");
- }catch (Exception e) {
- $result = $result1.substring(0, $result1.length());
- // TODO: handle exception
- }
这样还不行,解密出来的code中文部分仍是乱码。
所以在uc.java的$code = new Client().uc_authcode($code, "DECODE");这句下面还要加上$code = new String($code.getBytes("GBK"),"UTF-8");
可能有人会说直接转成utf-8不行吗?为什么要先转成gbk呢?如果直接转成utf-8的话,解密出来的$code是""。
到此中文的问题就得到解决了。笔者下载的是GBK版本的discuz,其他情况自己改一下编码应该没问题。
至此,只要我们在doAnswer()方法里添加我们自己的逻辑代码就已经能实现java和discuz的同步了。
另外,有个问题提醒大家,就是在discuz那边修改密码的时候,ucenter并不是马上发出通知的,这可能会引起同步和安全的问题。
文章转载自:《java整合discuz小结(实现与论坛同步登录等操作)》
java J2EE与DiscuzX3.2的UCenter实现单点登录的更多相关文章
- ucenter的单点登录
所谓单点登录,无非就是几个站点共用一个用户中心,实现同步登陆,同步退出. 服务器端:Loog SSO . 客服端: ucenter,说实话dz商业化确实让php发展了不少. ucenter 基本原理: ...
- 重学 Java 设计模式:实战装饰器模式(SSO单点登录功能扩展,增加拦截用户访问方法范围场景)
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 对于代码你有编程感觉吗 很多人写代码往往是没有编程感觉的,也就是除了可以把功能按照固 ...
- Yii整合ucenter实现单点登录
原文:http://www.php2.cc/article-1349-1.html 准备工作 1.下载ucenter源码,并安装好 2.下载ucenter开发源码,根据自己的项目下载对应版本(utf- ...
- java集成微软的ad域,实现单点登录
1.ad域介绍: windos server 2008R2服务器下的ad域,见下图(我是在虚拟机安装到windos server) 2.连接ad域代码:(里面代码自行修改) public Result ...
- Java架构师必知:什么是单点登录,主要会应用于哪些场景?
单点登录在大型网站里使用得非常频繁,例如,阿里旗下有淘宝.天猫.支付宝,阿里巴巴,阿里妈妈,阿里妹妹等网站,还有背后的成百上千的子系统,用户一次操作或交易可能涉及到几十个子系统的协作,如果每个子系统都 ...
- java和Discuz论坛实现单点登录,通过Ucenter(用户管理中心)
标题有点问题,没有进行修改. 一 Discuz论坛搭建步骤 1:服务器环境配置 服务器要支持php语言+支持mysql 5.0以上的数据库 + Apache服务器(支持网站的一个服务器,通过域名的能访 ...
- UCenter在JAVA项目中实现的单点登录应用实例
Comsenz(康盛)的UCenter当前在国内的单点登录领域占据绝对份额,其完整的产品线令UCenter成为了账号集成方面事实上的标准. 基于UCenter,可以将Comsenz旗下的Discuz! ...
- 点单登录原理和java实现简单的单点登录
引用自:http://blog.csdn.net/zuoluoboy/article/details/12851725 摘要: 单点登录(SSO)的技术被越来越广泛地应用到各个领域的软件系统当中.本文 ...
- 单点登录与消息队列以及在J2EE中的实现方案
前言 这次为大家简单介绍两个在WEB开发中经常使用的概念——单点登录和消息队列以及具体到J2EE中的一些实现方案.本文原创性的工作比较少,主要是一些总结概括和自己的理解. 单点登录SSO SSO的业务 ...
随机推荐
- Ubuntu14.04+Beanstalkd1.9最佳实践
目录 [TOC] 1.基本概念 1.1.什么是Beanstalkd? Beanstalkd 是一个轻量级消息中间件,它最大特点是将自己定位为基于管道 (tube) 和任务 (job) 的工作队列. ...
- LeetCode----Tree
Path Sum II 思路:回溯 public List<List<Integer>> pathSum(TreeNode root, int sum) { List<L ...
- java1234教程系列笔记 S1 Java SE chapter 02 lesson 03 java基本数据类型
第二章 第三节 数据类型 3.1 分类 基本数据类型.引用类型 3.2整型 byte 8 short 16 int 32 long 64 作业: A:1-10求和 B:float double 的最 ...
- [Linux] - Docker制作nginx+php
使用Docker制作nginx+php的镜像,这里的镜像是centos + nginx 1.9.7 + php 5.6.14 首先下载到nginx和php: nginx-1.9.5.tar.gz 下载 ...
- IOS开发-影院选座算法 限制产生孤座
众所周知目前影院选座是不允许随便选的,我们不可以任性的挑三拣四,最后留下N个单独的座位,目的就是要留下至少2个连着的座位: 另外有些影院的座位摆放并不是规则的,有些座位被过道或者特殊座位分割开,产生了 ...
- iis WebSocket 搭建环境及配置
http://www.86y.org/art_detail.aspx?id=816 WebSocket是html5新增加的一种通信协议,目前流行的浏览器都支持这个协议,例如Chrome,S ...
- python---psutil
系统性能信息模块psutil psutil是一个跨平台库,能够轻松实现获取系统运行的进程和系统利用率(CPU,内存,磁盘,网络等)信息,主要应用于系统监控,分析和限制系统资源及进程的管理,它实现了同等 ...
- 可提高工作效率的 PL/SQL Developer 设置
1.将Window List 列表展示出来并保存当前布局 ①Tools-->Windows List (展示窗口列表) ②Window-->Save Layout (保存当前布局) 2.设 ...
- 磁盘的读写-想起了SGA PGA DBWR LGWR...
衡量性能的几个指标的计算中我们可以看到一个15k转速的磁盘在随机读写访问的情况下IOPS竟然只有140左右,但在实际应用中我们却能看到很多标有5000IOPS甚至更高的存储系统,有这么大IOPS的存储 ...
- C# char 和string之间转换
har数组要转换成string可没想象的那么容易.需要使用到System.Text.StringBuilder!实例如下: char[] temp={a,b,c};System.Text.String ...