门户定制案例-自定义登录 URL
运行效果
登录系统时,不使用系统默认的登录 url,改为使用自定义地址,登录后返回 token
从功能树打开菜单时,url 中带上登录返回的 token和平台的 token
实现方法
- 定制企业门户应用,参考《门户定制》
- 在“门户自定义”组件中,添加自定义登录服务
- 在“门户自定义”组件中修改 $.config.components.uixContainer.UserImplement.loginUrl 为上一步添加的登录接口
在组件中添加服务
开启组件开发后,“端”列表中会显示出“门户自定义”组件,如下图所示
切换到该组件,在“服务”设计页中添加服务:自定义登录 customLogin,用法和桌面端一致,如下图所示
自定义登录的 Java 代码如下
public String customLogin(String username,String password) throws Exception {
// 密码解密
password = PasswordUtil.decode(password.trim());
// 用自己的方式验证username和password,不满足抛异常throw new BaseRuntimeException
// 获取用户信息
JSONArray users = ServiceUtil.get(SpringWebUtil.getRequest(), "entry",
"/uaa/dbrest/users?phoneNumber=eq." + username, null, JSONArray.class);
if (users.size() == 0) {
throw new BaseRuntimeException("001", HttpStatus.UNAUTHORIZED.value(), "手机号不存在", null);
}
JSONObject user = users.getJSONObject(0);
String user_id = user.getString("id");
String user_name = user.getString("username");
// 获取token
String credentialToken = ContextUtil.getEnv("CREDENTIAL_TOKEN");
String token = ServiceUtil.post(SpringWebUtil.getRequest(), "entry",
"/uaa/sso/token?username=" + user_name + "&credentialToken=" + credentialToken, null, String.class);
// 使用token登录
String session = AuthUtil.tokenLogin(ServiceUtil.getServiceUrl("entry"), token);
if (StringUtils.isNotEmpty(session)) {
HttpServletResponse response = SpringWebUtil.getResponse();
Cookie cookie = new Cookie("user_session", session);
cookie.setHttpOnly(false);
if ("https".equals(ContextUtil.getProtocol())) {
cookie.setSecure(true);
}
cookie.setPath("/");
cookie.setMaxAge(60 * 60 * 8);
response.addCookie(cookie);
JSONObject jsonObject = new JSONObject();
jsonObject.put("user_id", user_id);
//自定义获取第三方token逻辑
jsonObject.put("token", "第三方token");
return jsonObject.toJSONString();
} else {
throw new BaseRuntimeException("001", HttpStatus.UNAUTHORIZED.value(), "用户登录失败", null);
}
}
特别说明
- 前端传过来的密码需要解密
- 验证后,使用 CREDENTIAL_TOKEN 登录平台
- 平台的 Token 作为 cookie 返回
- 返回值中必须包含 user_id
- 服务对应的请求地址,实际使用时都是小写,详细请求地址请参考 controller 文件
- 除了上传通过api请求获取用户数据外,还可以通过新增 springboot.embed 文件,来实现与 main 模块关联使用
添加扩展点
门户的扩展点方法写在 /UI2/comp/portalConfig/components/portalConfig/portalConfig.config.js 文件的 onConfigContextInit 方法中
门户页 /entry/pcxapp/pcx/index.w 中提供处理菜单数据的扩展点 onProcessMenu,代码如下
//自定义处理菜单数据
let defineMenus = await this.getConfig('onProcessMenu')?.({ menus });
在 /UI2/comp/portalConfig/components/portalConfig/portalConfig.config.js 文件中添加扩展点 onProcessMenu,代码如下
async onConfigContextInit(configContextProcessor) {
let _this = configContextProcessor.page;
let portalConfig = {
"config": {
"components": {
"uixContainer": {
"UserImplement": {
"loginUrl": 登录url
"loginResultProcess":(res)=>{//处理登录返回数据
}
}
}
},
"/entry": {
"/pcxapp": {
"/pcx": {
"/index.w": {
"onProcessMenu": ({ menus }) => {
return menus;
}
}
}
}
}
}
};
//处理自定义内容
merge(_this.configContext, portalConfig);
ConfigContextProcessor.enhancePageAdvice(_this);
}
完整代码
/UI2/comp/portalConfig/components/portalConfig/portalConfig.config.js 文件的完整代码如下
import { merge } from "lodash";
import ConfigContextProcessor from 'core/framework/ConfigContextProcessor';
import React from 'react';
import URI from 'urijs';
import store from 'store';
export default {
processConfigContext(configContext) {
},
//递归处理数据
dfsFindClass(data, condition, doSomeThing) {
for (let i = 0; i < data.length; i++) {
let item = data[i];
if (item.hasOwnProperty("children")) {
item.children = this.dfsFindClass(item.children, condition, doSomeThing);
} else if (condition(item)) {
doSomeThing(item);
}
}
return data;
},
//自定义
async onConfigContextInit(configContextProcessor) {
//获取当前页
let _this = configContextProcessor.page;
let portalConfig = {
"config": {
"components": {
"uixContainer": {
"UserImplement": {
//设置登录url
"loginUrl": "/portalconfig/login/customlogin",//注意请求地址大小写,系统默认都是小写
//处理登录返回数据
"loginResultProcess":(res)=>{
//获取登录返回的数据
store.set('thirdToken', res.data?.token)
}
}
}
},
"/entry": {
"/pcxapp": {
"/pcx": {
"/index.w": {
"onProcessMenu": ({ menus }) => {
this.dfsFindClass(menus, item => item.url?.indexOf("token") > -1, item => {
//获取平台token并进行参数修改
let uri = new URI(item.url);
const { token } = uri.query(true);
if (token) {
uri.setQuery({ token2: token });
//设置第三方系统登录反馈的token信息
uri.setQuery({ token: store.get("thirdToken") });
}
item.url = uri.toString();
})
return menus;
}
}
}
}
}
}
};
//处理自定义内容
merge(_this.configContext, portalConfig);
ConfigContextProcessor.enhancePageAdvice(_this);
}
}