易班轻应用授权免登
本文主要介绍易班开放平台如何以轻应用的方式实现业务系统授权免登。轻应用在使用时,可以支持仅在易班客户端访问业务系统,也支持在客户端、PC/手机浏览器都可以访问业务系统。
1.创建轻应用
登录易班开放平台,https://o.yiban.cn/,进入管理中心,点击并创建轻应用,创建时,会要求用户填写维护地址和应用地址,就直接填写对应的业务系统的地址即可。
创建完成后,会生成一个轻应用,开发时将用到的关键信息有 AppId,AppSecret,以及站内地址,具体用法下文会讲到。
2.解析用户授权信息
在写代码之前,首先下载一个易班官方提供的工具包,在密文解析的时候可能会用到。https://open.yiban.cn/wiki/download/YBApi_sdk_java.zip
在易班客户端的应用广场找到你创建的轻应用,并点击时客户端会向你的应用系统发起请求,并且请求会携带2个参数,verify_request 和 yb_userId。
首先获取参数,并进行解析,如果解析后的结果是已授权的用户信息,则直接实现业务系统的免登逻辑(具体需要读者自己实现);如果发现用户信息未授权,需要先进行易班授权,授权成功后会再次重定向到业务系统。
//易班轻应用的集成
if(org.apache.commons.lang.StringUtils.isNotEmpty(request.getParameter("verify_request"))) {
String yibanAppId=String.valueOf(thirdProperties.get("yibanAppid"));
String yibanAppSecret=String.valueOf(thirdProperties.get("yibanAppSecret"));
YiBanUserInfo yibanUserInfo= AESTranferUtil.jsonCode(request.getParameter("verify_request"), yibanAppSecret, yibanAppId);
if(yibanUserInfo!=null) {
context.getFlowScope().put("yiban", "yiban");
context.getFlowScope().put("yibanCallback", String.valueOf(thirdProperties.get("yibanCallbackUrl")));
context.getFlowScope().put("yibanAppid", String.valueOf(yibanAppId));
if(org.apache.commons.lang.StringUtils.isNotEmpty(yibanUserInfo.getUserId())) {//此时已经通过易班授权,不必再走登录页的js逻辑
context.getFlowScope().put("yibanUserInfo", yibanUserInfo);
}
}
}
这里要着重讲解的就是verify_request参数的解密,verify_request加密字符串使用了AES-128-CBC对称加密算法,其中应用的AppSecret为解密的密钥,AppID为向量。 官方提供了php版本的解密方式,下面是本人用java方式实现的。
// 默认的加密算法
private static final String CIPHER_ALGORITHM = "AES/CBC/NOPadding";
// 编码
private static final String ENCODING = "UTF-8";
// 算法
private static final String ALGORITHM = "AES";
/**
* 将hex格式转化成十进制
*/
public static byte[] hexToByte(String hex) {
int m = 0, n = 0;
int byteLen = hex.length() / 2; // 每两个字符描述一个字节
byte[] ret = new byte[byteLen];
for (int i = 0; i < byteLen; i++) {
m = i * 2 + 1;
n = m + 1;
int intVal = Integer.decode("0x" + hex.substring(i * 2, m) + hex.substring(m, n));
ret[i] = Byte.valueOf((byte) intVal);
}
return ret;
}
/**
* AES密文解析
* @param data
* 要解密的内容
* @param key
* 密码
* @param offset
* 偏移量
* @return
* @throws Exception
*/
public static String decrypt(String data, String key, String offset) throws Exception {
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("ASCII"), ALGORITHM);
IvParameterSpec iv = new IvParameterSpec(offset.getBytes());// 使用CBC模式,需要一个向量iv,可增加加密算法的强度
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] buffer = hexToByte(data);
byte[] encrypted = cipher.doFinal(buffer);
return new String(encrypted, ENCODING);// 此处使用BASE64做转码。
}
/**
* 将易班请求参数中的密文解析出用户信息
* @param data 要解密的内容
* @param key 密码 (appSecret)
* @param offset 偏移量 (appId)
* @return 关于返回值,如果返回的对象为空,说明是非法的密文,走正常登录;
* 如果对象的用户id登信息为空,未授权;不为空,已授权
*/
public static YiBanUserInfo jsonCode(String data, String key, String offset){
try {
String plaintext= decrypt(data,key,offset);
JSONObject plainJson= JSONObject.fromObject(plaintext.trim());
Object visit_oauth= plainJson.get("visit_oauth");
if(visit_oauth instanceof Boolean) {
if(false==(Boolean)visit_oauth) {
System.err.println("未授权");
return new YiBanUserInfo();
}
}
if(visit_oauth instanceof JSONObject) {
JSONObject oauthJson=(JSONObject)visit_oauth;
if(oauthJson.get("access_token")!=null) {
System.err.println("已授权");
JSONObject visitUser=(JSONObject) plainJson.get("visit_user");
YiBanUserInfo yiBanUserInfo=new YiBanUserInfo();
yiBanUserInfo.setUserId(visitUser.getString("userid"));
yiBanUserInfo.setUserName(visitUser.getString("username"));
yiBanUserInfo.setUserNick(visitUser.getString("usernick"));
return yiBanUserInfo;
}
}
visit_oauth.toString();
}catch (Exception e) {
e.printStackTrace();
}
return null;
}
在解析时可能存在报错,java.security.InvalidKeyException: Illegal key size,之前下载好的sdk包中,有个Java-AES256 补丁包,将对应jdk的两个jar包替换自己的 ${JAVA_HOME}/jre/lib/security的jar包
3.易班授权
当解析的用户信息是未授权的,需要先重定向到易班的站内地址进行授权操作,代码实现较为简单
var APPID="${yibanAppid}";
var callbackuri="${yibanCallback}";
var state="${yibanState}";
var uri="https://oauth.yiban.cn/code/html?client_id="+APPID+"&redirect_uri=";
uri = uri+encodeURIComponent(callbackuri)+'&state='+state;
window.location.href=uri;
需要说明的是,callbackuri 就是上文提到的站内地址(别当成是自己业务应用的地址了),state参数值可以自定义。
4.授权后实现免登
当进行易班授权之后,请求将重定向到业务系统,参考步骤二,再次解析
用户信息,不过此时用户信息已授权,可以拿到userid,username等关键信息,根据这些信息,实现自己系统的免登逻辑。
这里补充一句,开发时可能会出现获取的易班用户信息与实际的业务系统的用户信息无法完全一致的情况,可以在第一次授权登录时将易班信息与业务表的用户信息进行数据绑定,在之后的授权登录时就可以直接登录到对应的用户了,具体逻辑由读者自己实现。
5.小结
至此易班的轻应用授权免登就完成了,整体的思路就是将密文解析出用户信息,如果用户未授权,先进行易班授权,授权之后再次解析出关键的用户信息,根据用户信息实现免登。整体流程实现比较简单,希望可以帮到大家。