自定义登录请求
场景描述
不使用平台提供的短信配置,开发者自行发送验证码,使用手机号和验证码进行登录
实现思路
平台在用户组件中提供了登录方法,在登录前事件中,修改平台默认的登录请求url为自定义的登录请求url,在自定义的登录请求中会收到username和password两个参数,这两个参数的内容来自登录对话框,本例表示手机号和验证码
自定义登录请求中的逻辑如下
- 密码解密,收到的password是加密的,需要先解密
- 用自己的方式验证username和password,不满足抛异常
- 用手机号获取用户id和用户名
- 使用credentialToken和用户名获取用户token
- 使用token登录,获得user_session,写入response的Cookie
- 返回用户id
实现步骤
1. 定义登录请求
开启门户定制,在服务中添加自定义登录请求,POST方法,包括username和passwrod两个参数,返回字符串,如下图所示:
实现代码如下:
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);
return jsonObject.toJSONString();
}else{
throw new BaseRuntimeException("001",HttpStatus.UNAUTHORIZED.value(),"用户登录失败",null);
}
}
代码中引用的类如下:
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import com.justep.util.ContextUtil;
import com.justep.util.SpringWebUtil;
import com.justep.util.net.AuthUtil;
import com.justep.util.net.ServiceUtil;
import com.justep.util.PasswordUtil;
import com.justep.lang.exception.BaseRuntimeException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONArray;
2. 调用登录请求
在门户登录页login.w中,登录按钮点击事件,存储登录类型,给门户主页的用户组件使用。在UI2/pc/userDialog/login.js中添加 loginBtnClick 方法
Model.prototype.loginBtnClick = function (event) {
window.loginType = this.type.get();//存储登录类型
this.login();
};
在门户主页index.w的用户组件的登录前事件中,判断如果是短信登录,则设置登录请求的url为自定义的登录请求url。在UI2/pc/index.js中添加 onUserBeforeLogin 方法
Model.prototype.onUserBeforeLogin=function(event){
if(window.loginType=='smsCode'){//短信登录
//设置登录请求的url为自定义的登录请求url
event.option.url="/entry/main/fuwu/customlogin";
}
//下面的代码为用户组件默认代码,给予保留
//优化统一租户第二次登录
var currentTenant = location.host.split("-")[0];
if(currentTenant != this.DEFAULT_TENANT){
var Uaa = require("$UI/system/components/justep/user/js/uaa");
var param = window.location.search;
var paramUseUnionUser = param.indexOf("useUnionUser");
//var paramChangeTenant = localStorage.getItem("changeTenant");
//if(paramUseUnionUser != -1 && !paramChangeTenant){
if(paramUseUnionUser != -1){
Uaa.changeBaseUrl(this.DEFAULT_TENANTUrl);
loadingBar.start();
this.checkCommonServiceHealth();//检查common租户是否启动完
}
}
}