关于Discuz与它的UCenter我就不做介绍了,网上一搜一大把。
目前公司做了个项目,其中论坛模块用的就是Discuz,然后给我分配了登陆、注册这些模块。很不巧,我不明白Discuz和UCenter,于是只好问公司的大牛和自己百度资源。终于搞得差不多的时候,又发现,自己有点不会用它,不知道怎么跟java代码来结合。于是,就各种找,找了好多好多,都没个具体的,然后自己通过网上找的,以及请教公司大牛,最终解决了这个问题。
话不多说,我就直接上代码。
当然,首先你得下载安装Discuz,关于怎么安装,我也不详细说,你懂的,网上有资源。
安装完之后,得去UCenter的应用管理进行一些配置,具体怎么配置,也不多说,自己找,我只说一下应用的主URL指的是你本地写的代码的主URL。
然后自己去网上下载一下Discuz的API,也就是JAVA_UCenter的API,结构是这样的:
下载好后,放进自己的项目里面:
接着,就是弄个配置文件:
UC_API那里填写的是Discuz的东西,要是你是在本地测,就跟我那样填写就对了,UC-APPID指的是之前在应用管理中添加的应用的ID,其余不填都可以。
接着,因为这个项目是SpringBoot项目,而需要给Discuz弄个servlet,然后SpringBoot又没有web.xml文件,怎么弄呢?只需要在SpringBoot的启动代码里面写一些东西就行:
这样就好了。
接下来就是登陆注册的实现了。因为我这个要求弄成单点登陆,也就是登陆了论坛,就不用再登陆其它子系统,也就是本地应用也登陆,然后注册也是一样,所以需要在Discuz的登陆注册上添加自己的登陆注册,具体代码:
先弄了个常量类:
public class UserConstant {
public static final String ADMINISTRATOR = "管理员";
public static final String CONSUMER = "普通用户";
public static final String NOT_FOUND = "用户不存在,或者被删除";
public static final String WRONG_PASSWORD = "密码错误";
public static final String UNDEFINED = "未定义";
public static final String LOGIN_FAILURE = "登陆失败";
public static final String NAME_EXISTS = "用户名已存在";
public static final String NAME_ILLEGAL = "用户名不合法";
public static final String INCLUDE = "包含要允许注册的词语";
public static final String EMAIL_ERROR = "Email格式有误";
public static final String EMAIL_BLACKLIST = "Email不允许注册";
public static final String EMAIL_EXISTS = "邮箱已存在";
public static final String REGISTER_SUCCESSFUL = "注册成功";
public static final String ABNORMAL = "数据库或者服务器异常,注册失败,请联系管理员!";
}
然后登陆注册:
@Controller
@RequestMapping("/api/user")
public class UserController extends BaseController {
@Autowired
private IUserService userService;
@PostMapping("/login")
@ResponseBody
public ResponseEntity> login(@Param("loginName") String loginName, @Param("password") String password) {
//转换为MD5后进行登陆查询
User user = userService.login(loginName, MD5Utils.getPwd(password));
//结合discuz的UCenter进行登陆
Client e = new Client();
String result = e.uc_user_login(loginName, password);
LinkedList rs = XMLHelper.uc_unserialize(result);
if (rs.size() > 0) {
int $uid = Integer.parseInt(rs.get(0));
if ($uid > 0 && user != null) {
//本地登陆代码
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(loginName, password);
subject.login(token);
Session session = subject.getSession();
session.setAttribute("loginId", user.getId());
if (UserConstant.ADMINISTRATOR.equals(user.getRole())) {
return success(user.getRole());
} else {
return success(user.getRole());
}
} else if ($uid == -1) {
return error(UserConstant.NOT_FOUND);
} else if ($uid == -2) {
return error(UserConstant.WRONG_PASSWORD);
} else {
return error(UserConstant.UNDEFINED);
}
} else {
return error(UserConstant.LOGIN_FAILURE);
}
}
@PostMapping("/register")
@ResponseBody
public ResponseEntity> register(User user){
//查询用户名是否已经被注册
Integer userCount = userService.getUserCount(user.getLoginName());
if (userCount > 0){
return error(UserConstant.NAME_EXISTS);
}else {
//结合discuz的UCenter进行登陆
user.setRole(UserConstant.CONSUMER);
Client uc = new Client();
String $returns = uc.uc_user_register(user.getLoginName(), MD5Utils.getPwd(user.getPassword()), user.getEmail1());
int $uid = Integer.parseInt($returns);
if ($uid <= 0) {
if ($uid == -1) {
return error(UserConstant.NAME_ILLEGAL);
} else if ($uid == -2) {
return error(UserConstant.INCLUDE);
} else if ($uid == -3) {
return error(UserConstant.NAME_EXISTS);
} else if ($uid == -4) {
return error(UserConstant.EMAIL_ERROR);
} else if ($uid == -5) {
return error(UserConstant.EMAIL_BLACKLIST);
} else if ($uid == -6) {
return error(UserConstant.EMAIL_EXISTS);
} else {
return error(UserConstant.UNDEFINED);
}
} else {
//本地注册
//注册密码MD5加密
user.setPassword(MD5Utils.getPwd(user.getPassword()));
try {
userService.userRegister(user);
return success(UserConstant.REGISTER_SUCCESSFUL);
} catch (Exception e) {
return error(UserConstant.ABNORMAL);
}
}
}
}
}
然后,还有一个问题,就是用到了Shiro做权限和登陆拦截,那么,需要我们放开Discuz的登陆注册,也就是diamante中注释的放开UC,具体代码是这样的:
@Configuration
public class ShiroConfiguration {
//将自己的验证方式加入容器
@Bean
public MyRealm myShiroRealm() {
MyRealm myRealm = new MyRealm();
return myRealm;
}
//权限管理,配置主要是Realm的管理认证,本项目暂时未用到
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
return (SecurityManager)securityManager;
}
//Filter工厂,设置对应的过滤条件和跳转条件
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager((SecurityManager) securityManager);
Map map = new HashMap();
//放开swagger
map.put("/swagger/**","anon");
//放开UC
map.put("/**/api/**","anon");
//放开静态资源
map.put("/resources","anon");
//放开注册
map.put("/api/user/register","anon");
//对所有用户认证
map.put("/**","authc");
// shiroFilterFactoryBean.setUnauthorizedUrl("/swagger/index.html");
//登录
shiroFilterFactoryBean.setLoginUrl("/api/user/login");
//首页
// shiroFilterFactoryBean.setSuccessUrl("/swagger/index.html");
//错误页面,认证不通过跳转
shiroFilterFactoryBean.setUnauthorizedUrl("/api/user/login");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
return shiroFilterFactoryBean;
}
//加入注解的使用,不加入这个注解不生效
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
}