日期:2014-05-16  浏览次数:20404 次

[转]Discuz!论坛通行证与JSP网站的整合
1.需求
需求:本项目网站需要和Discuz论坛实现同步登录、注销与注册。
2.引言.
Discuz论坛提供的Passport(通行证)接口可以很好的实现上述需求。通行证可以在Discuz论坛的系统设置中开启,开启通行证之后的论坛将不再接受除管理员以外的用户的登录请求,而与应用网站进行统一登录管理。整合之后的用户注册、登录、注销流程,请阅读参考资料[1],强烈建议看本文档之前先看一下参考资料[1],熟悉一下整合的流程。本文档的大部分代码是参照上面所说的文章,在其基础上修改而来。下面介绍实现的整个流程,并给出完整代码。
3.流程
应用程序与论坛整合的大体流程是:1、开发加密、解密类,以及密钥类 2、修改应用程序的登录、注销、注册的页面,使其能够满足同步登录的需要 3、在Discuz论坛的系统设置中启用通行证,并设置应用网站的地址及私钥(当然,在调试阶段,通行证应该一直是处于启用状态的)。注:步骤2与3是没有先后顺序的,即一旦开始进行步骤2,无论是先做的登录、注销还是注册,都应该开启Discuz论坛的通行证,以方便测试,否则即使代码正确也不会实现同步。
4.涉及的页面(以下URL为举例)
Discuz! 的 URL 为http://127.0.0.1:8088/index.php
项目程序的 URL 为http://localhost:8081/
项目程序的注册页面为user/userregpre.do
项目程序的登录页面为index.do
项目程序的退出页面为user/userlogout.do
以上这些会在下面的代码中和discuz论坛的通行证的配置中用到。
5.实现过程
5.1 开发DiscuzPassport及Encryption两个类,实现与Discuz一致的数据加密。这两个类是由上文说的成熟案例得到。经测试这两个类方法完全符合要求并且无错误,所以直接套用即可。

-----DiscuzPassport.java-----

import java.io.UnsupportedEncodingException;
import java.util.Map;
import java.util.Iterator;
import java.util.Random;
import java.util.Set;
import sun.misc.BASE64Decoder;



public class DiscuzPassport {

public static String encrypt(String src, String key) {
  Random random = new Random();
  random.setSeed(System.currentTimeMillis());
  String rand = "" + random.nextInt() % 32000;
  String encKey = Encryption.generateKey(rand, "MD5");
  int ctr = 0;
  String tmp = "";
  for (int i = 0; i < src.length(); i++) {
   ctr = (ctr == encKey.length() ? 0 : ctr);
   tmp += encKey.charAt(ctr);
   char c = (char) (src.charAt(i) ^ encKey.charAt(ctr));
   tmp += c;
   ctr++;
  }
  String passportKey = passportKey(tmp, key);
  return new sun.misc.BASE64Encoder().encode(passportKey.getBytes());
}

public static String decrypt(String src, String key) {
  byte[] bytes = null;
  try {
   bytes = new BASE64Decoder().decodeBuffer(src);
   src = new String(bytes);
  } catch (Exception e) {
   return null;
  }
  src = passportKey(src, key);
  String tmp = "";
  for (int i = 0; i < src.length(); ++i) {
   char c = (char) (src.charAt(i) ^ src.charAt(++i));
   tmp += c;
  }
  return tmp;
}

public static String passportKey(String src, String key) {
  String encKey = Encryption.generateKey(key, "MD5");
  int ctr = 0;
  String tmp = "";
  for (int i = 0; i < src.length(); ++i) {
   ctr = (ctr == encKey.length() ? 0 : ctr);
   char c = (char) (src.charAt(i) ^ encKey.charAt(ctr));
   tmp += c;
   ctr++;
  }
  return tmp;
}

public static String passportEncode(Map data) {
  Set keys = data.keySet();
  String key = "";
  String ret = "";
  Iterator iterator = keys.iterator();
  while (iterator.hasNext()) {
   key = (String) iterator.next();
   try
   {
    ret += key + "=" + (String) data.get(key) + "&";
   }
   catch (Exception e)
   {
    return "";
   }
  }
  if (ret.length() > 0)
   return ret.substring(0, ret.length() - 1);
  return "";
}
}

------------------------------


-----Encryption.java-----

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;