通过discuzX2.5 社区与java 的单点登录的实现(测试)

没错。就是用Ucenter。

.在叙述的过程中,我很多不必要的步骤会忽略,所以看这篇文章前需要的基础:

1.会基本使用discuz。

2.有最基本相关的java web基础。

3.有基本的php基础。



一。准备工作:

1.首先去安装discuz x2.5。去官方网下载最新版。

2.安装的时候选discuzx2.5 带UCenter版,因为带UCenter 不用自己另外安装UCenter,如果自己安装UCenter的话,到时候同步登录的时候,发觉同步的不是同一账户。(至于怎样安装,自己百度)

3. 下载java与UCenter的借口包:http://code.google.com/p/discuz-ucenter-api-for-java。这个包很强大,感觉提供这个包的作者。


二、java与Ucenter通信

1.进入到UCenter后台,添加应用。

       安装方式:自定义
      应用类型:其他
      应用名称:JAVA项目名称,可随意
      应用主URL:JAVA项目的访问地址,例如:http://localhost:8080/XXX
      通信密钥:任意字符,例如:123456
      应用接口文件名称:uc.php,这个不要改,前面也不要加/api/,UCenter在与其通信时会自动转换为:http://localhost:8080/javaTest/api/uc.php
     是否开启同步登录:是
     是否接受通知:是
     以上的配置项必填,其他保持为空即可。
     点击“提交”,保存成功后,记下该JAVA应用的APPID,下面的配置中会需要。
     此时返回应用列表,UCenter会自动进行通信验证,不出意外肯定会出现“通信失败”的字样,先不必管它。


2.java端的配置

        2-1、从“discuz-ucenter-api-for-java”的开源项目网站中下载相关的API文件
2-2、将JAVA_UCenter.zip解压、覆盖到你的JAVA项目中,其中的新文件有:
                  src/config.properties:本地的JAVA项目与UCenter的接口配置文件(需要根据实际环境进行配置)
src/api/ucenter/Base64.java
src/api/ucenter/Client.java:将常用的UCenter操作封装成的客户端对象,我们在项目中主要用它来与UCenter打交道
src/api/ucenter/PHPFunctions.java
src/api/ucenter/UC.java:本地的JAVA项目用来接收UCenter同步命令的Servlet接口,其访问地址必须为:/api/uc.php
src/api/ucenter/XMLHelper.java
WebRoot/WEB-INF/web.xml:主要就是将src/api/ucenter/UC.java定义为Servlet

(1) src/config.properties中的代码如下:
# ================================================
# Ucenter API for JAVA
# ================================================
UC_API = http://localhost
UC_IP = 
UC_KEY = 123456
UC_APPID = 2
UC_CONNECT = 

其中,UC_API表示UCenter的访问地址,UC_KEY就是在UCenter中添加新应用时定义的通信密钥,UC_APPID表示新应用的APPID,就是刚才记下的那个。
除这三项外,其他的配置保持为空即可。


(2) WebRoot/WEB-INF/web.xml中的代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" 
    xmlns="http://java.sun.com/xml/ns/j2ee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    
  <servlet>
    <display-name>同步UC Server发出的操作指令</display-name>
    <servlet-name>UC</servlet-name>
    <servlet-class>api.ucenter.UC</servlet-class>
    <load-on-startup>2</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>UC</servlet-name>
    <url-pattern>/api/uc.php</url-pattern>
  </servlet-mapping>
  
</web-app>

别的无所谓,只需注意这一行:<url-pattern>/api/uc.php</url-pattern>

2-3、JAVA端配置完成,在eclipse中启动调试模式
2-4、再次返回到UCenter的控制台,点击应用管理,此时应该会看到绿色的“通信成功”字样.

2-5 注册端的代码:

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("into do post");
		String name= request.getParameter("name");
		String pwd = request.getParameter("pwd");
		String email="[email protected]";
		System.out.println(name+","+pwd);
		
		Client uc = new Client();
		String $return = uc.uc_user_register(name, pwd,email);
		System.out.println($return);
		int $uid = Integer.parseInt($return);
		if($uid <=0){
			if($uid ==-1){System.out.println("用户名不合法");}
			else if($uid == -2){System.out.println("包含要允许注册的词语");}
			else if($uid == -3){System.out.println("用户名已经存在");}
			else if($uid == -4){System.out.println("Email 格式有误");}	
			else if($uid == -5){System.out.println("Email 不允许注册");}	
			else {System.out.println("未定义");}	
		}else {
			System.out.println("OK");
		}
	}

   2-6 登录端的代码:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("into do post");
		PrintWriter out=response.getWriter();
		
		String name= request.getParameter("name");
		String pwd = request.getParameter("pwd");
		String email="[email protected]";
		//System.out.println(name+","+pwd);
		
		
			request.setAttribute("username", name);
		
			 Client uc = new Client();
			 String $result =uc.uc_user_login(name, pwd);
			 String $ucsynlogin="";
			 LinkedList<String> rs = XMLHelper.uc_unserialize($result);
			 String $username=null;
			 String $password=null;
			 int $uid=0;
			 if(rs.size()>0){
				 
				  $uid = Integer.parseInt(rs.get(0));	
				  $username = rs.get(1);
				  $password = rs.get(2);
				  System.out.println($username+","+$password+","+$uid);
				if($uid > 0){
					 $ucsynlogin = uc.uc_user_synlogin($uid);
				}else if($uid == -1){
					System.out.println("用户不存在,或者被删除");
				}else if($uid == -2){
					System.out.println("密码错误");
				}else{
					System.out.println("未定义");
				}
				 
			 }// if
			 
			 //设置本地discuz登录的cookie信息,cookie存活时间
			 //直接访问论坛就可以有用户信息了
		     try{
		    	 response.setCharacterEncoding("utf-8");
		    	 //同步cookie信息
		    	 response.addHeader("P3P", "CP=\"CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR\"");
		    	 Cookie auth = new Cookie("auth", uc.uc_authcode($password+"\t"+$uid, "ENCODE"));
		    	 auth.setMaxAge(31536000);
		    	 
		    	 //添加到session
		    	 request.getSession().setAttribute("user", $username);
		    	 
		    	 out.write($ucsynlogin);
		    	 out.flush();
		    	 out.write("success");
		    	 out.flush();
		     }catch(Exception e){
		    	 e.printStackTrace();
		     }
		
		
	}

            2-7 java网站退出,论坛同步退出
1> 步骤说明:
java网站网站注销 > 调用Client里面的uc_user_synlogout同时注销论坛用户

2> 具体代码实现(仅供参考)
Client uc = new Client();
String $ucsynlogout = uc.uc_user_synlogout();
System.out.println("退出成功"+$ucsynlogout);
return $ucsynlogout;

2-8 java网站修改用户信息同步论坛资料信息
1> 步骤说明:
修改用户保存 > 获取之前论坛用户信息 > 调用接口进行修改uc_user_edit

2> 具体代码实现(仅供参考)
Client uc = new Client();
uc.uc_user_edit($username, $oldpw, $newpw, $email, $ignoreoldpw, $questionid, $answer)


三 论坛登录同步登录java网站web


我们来看看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登录同步java网站web网站登录,中文乱码问题
到这里,我们又遇到了中文的问题了,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,其他情况自己改一下编码应该没问题。
参考资料 http://my.oschina.net/u/1274710/blog/165570
参考资料 http://www.cnblogs.com/netWild/archive/2013/06/28/3161164.html



    





你可能感兴趣的:(通过discuzX2.5 社区与java 的单点登录的实现(测试))