门户定制案例-自定义登录 URL

运行效果

登录系统时,不使用系统默认的登录 url,改为使用自定义地址,登录后返回 token

图 4

从功能树打开菜单时,url 中带上登录返回的 token和平台的 token

图 3

实现方法

  1. 定制企业门户应用,参考《门户定制
  2. 在“门户自定义”组件中,添加自定义登录服务
  3. 在“门户自定义”组件中修改 $.config.components.uixContainer.UserImplement.loginUrl 为上一步添加的登录接口

在组件中添加服务

开启组件开发后,“端”列表中会显示出“门户自定义”组件,如下图所示

图 0

切换到该组件,在“服务”设计页中添加服务:自定义登录 customLogin,用法和桌面端一致,如下图所示

图 1

自定义登录的 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);
    }
}

results matching ""

    No results matching ""