Skip to main content

一、单点简述​

服务平台基于JWT(Json Web Token)协议的统一认证服务,可实现用户从第三方平台跳转登录至服务平台,即不需要再次登录的效果。官网地址:https://jwt.io

二、接入说明​

1、接入流程​

(1)对接方向服务平台提交单点申请,平台提供 baseUrl、appKey、appSecret 三组参数。

(2)对接方将用户字段信息签名加密生成 token。

(3)对接方携带 appKey 和 token 参数发起请求。

名词解释

1、公共参数说明:

${baseUrl}:平台提供的请求地址前缀

${appKey}:平台提供的唯一标识

${appSecret}:平台提供的密钥

2、请求地址​

入口类型访问链接
WEB端/移动端地址${baseUrl}/login/wechatlogincheck.html?appKey={厂商服务,平台提供}&token={鉴权凭证}

登录示例

根据平台提供的参数:baseUrl,appKey,token进行拼接【token需要进行JWT鉴权加密】

请求地址:${baseUrl}/login/wechatlogincheck.html?appKey={厂商服务,平台提供}&token={鉴权凭证}

请求示例:https://school.nicezhuanye.com/login/wechatlogincheck.html?appKey=xxx&token=xxx

3、请求参数​

参数名是否必填说明
appKey是平台提供的对接厂商唯一标识
token是鉴权凭证,参考签名方式

Payload 用户字段信息说明【Token】

参数名是否必填描述
userEID是用户EID 【平台ID/登录名/第三方厂商ID/自注册手机号/自注册第三方ID】
userType是用户类型【1: 学生,2: 老师,3: 家长】
schoolEID是学校EID【平台学校ID/第三方学校ID】【userEID使用登录名时,必填】
sysTime是当前时间戳,单位是秒
用户信息&注意事项

1、平台将自动校验userEID的所属类型【平台内设置】。

2、userEID支持五种类型:平台ID/登录名/第三方厂商ID/自注册手机号/自注册第三方ID。

3、userEID使用登录名时,schoolEID值不能为空,需要双方学校建立映射关系。

跳转地址&注意事项

单点登录跳转失败时,如需跳过服务平台登录页,可在URL添加参数直接跳转至错误页: &failUrl=https://school.nicezhuanye.com/login/error.html

关键字&注意事项

1、双方平台用户确定业务字段(学号,手机号,身份证)对接,由学校管理员进行数据维护即可。

2、双方平台用户对应机制依赖于第三方关键值映射表,该表需使用对应学校管理员账号维护。用户第一次跳转进入本平台访问时,需要在认证界面输入手机号进行关联账号,之后才能直接跳转。

三、JWT签名方式​

1、JWT创建步骤​

JWT由三部分组成:Header(头部)、Payload(负载) 和 Signature(签名),生成token的具体步骤如下,可参考官网【官网地址:https://jwt.io】:

1、创建Header对象

2、创建Payload对象

3、将Header和Payload进行Base64编码

4、使用Header,Payload,appSecret生成签名

5、拼接Header、Payload和Signature,生成完整JWT的token

2、JWT代码示例【java代码】​

/**
* @Description: JWT签名方式
* @author: hzy
* @create: 2026-02-28 17:29
*/
public class JwtUtil {

/**
* 平台提供的密钥
*/
private static String SECRET_KEY = "appSecret";

/**
* 生成token
* @param userEID
* @param userType
* @param schoolEID
* @return Header.Payload.Signature
*/
private static String generateToken(String userEID, String userType, String schoolEID) {
// 创建Header对象,并将算法和类型设置为固定值
JSONObject header = new JSONObject();
header.put("alg", "HS256");
header.put("typ", "JwtUtil");

// 创建Payload对象,设置需要携带的信息
JSONObject payload = new JSONObject();
long timeMillis = System.currentTimeMillis() / 1000;
payload.put("userEID", userEID);
payload.put("userType", userType);
payload.put("schoolEID", schoolEID);
payload.put("sysTime", timeMillis);

// 将Header和Payload进行Base64编码
String encodedHeader = Base64.getEncoder().encodeToString((header.toString().getBytes()));
String encodedPayload = Base64.getEncoder().encodeToString((payload.toString().getBytes()));

// 生成签名
String signature = generateSignature(SECRET_KEY, encodedHeader + "." + encodedPayload);

// 拼接Header、Payload和Signature,生成完整的JWT token
return encodedHeader + "." + encodedPayload + "." + signature;
}

/**
* 生成签名
*
* @param appSecret 平台提供的密钥
* @param data Header.Payload
* @return Signature
*/
private static String generateSignature(String appSecret, String data) {
try {
byte[] secretKeyBytes = appSecret.getBytes();
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKeyBytes, "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(secretKeySpec);
byte[] signatureBytes = mac.doFinal(data.getBytes());
return Base64.getUrlEncoder().encodeToString(signatureBytes);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

public static void main(String[] args) {
String token = generateToken("13900001234", "1", "25320316");
System.out.println("生成token信息: " + token);
}

}