Skip to content

组织授权与审计平台开放认证接口文档

本文档严格遵守OAuth2.0协议规范,并新增了补充逻辑。关于协议:https://oauth.net/2/

系统认证和用户同步流程图

用户授权登录流程图

一、系统授权流程接口

用户的成功登录依托于用户的关联。系统之间的用户通过关联关系进行一一对应,需要在调用用户授权认证接口前同步贵系统用户到组织授权平台。

为了方便理解,首先提供配置字典,下面的描述中会使用占位符

变量名中文名描述示例
platform-url平台外网地址授权平台的外网访问地址http://220.194.160.6:8088
server-url平台内网地址授权平台的内网访问地址http://192.168.26.37:5000
local-url系统地址系统的外网可访问地址http://localhost:8080
client-id系统身份id从平台申请的CIIntelij-community
client-secret系统身份密钥从平台申请的CSxxxxxxxxxxxxx
redirect-uri授权回调地址获取到授权码后回调处理的uri/oauth/callback(固定)
scope认证作用域约定的oauth认证作用域client(固定)

这里提供java的常量池,下面的示例会演示到:

java
/**
 * This class contains OAuth constants, used project-wide
 */
public interface OAuthConstants {

    String TIMESTAMP = "oauth_timestamp";
    String SIGN_METHOD = "oauth_signature_method";
    String SIGNATURE = "oauth_signature";
    String CONSUMER_SECRET = "oauth_consumer_secret";
    String CONSUMER_KEY = "oauth_consumer_key";
    String CALLBACK = "oauth_callback";
    String VERSION = "oauth_version";
    String NONCE = "oauth_nonce";
    String REALM = "realm";
    String PARAM_PREFIX = "oauth_";
    String TOKEN = "oauth_token";
    String TOKEN_SECRET = "oauth_token_secret";
    String VERIFIER = "oauth_verifier";
    String HEADER = "Authorization";
    String SCOPE = "scope";
    String BASIC = "Basic";

    // OAuth 1.0
    /**
     * to indicate an out-of-band configuration
     * @see <a href="https://tools.ietf.org/html/rfc5849#section-2.1">The OAuth 1.0 Protocol</a>
     */
    String OOB = "oob";

    // OAuth 2.0
    String ACCESS_TOKEN = "access_token";
    String CLIENT_ID = "client_id";
    String CLIENT_SECRET = "client_secret";
    String REDIRECT_URI = "redirect_uri";
    String CODE = "code";
    String REFRESH_TOKEN = "refresh_token";
    String GRANT_TYPE = "grant_type";
    String AUTHORIZATION_CODE = "authorization_code";
    String CLIENT_CREDENTIALS = "client_credentials";
    String STATE = "state";
    String USERNAME = "username";
    String PASSWORD = "password";
    String RESPONSE_TYPE = "response_type";
    String RESPONSE_TYPE_CODE = "code";

    //not OAuth specific
    String USER_AGENT_HEADER_NAME = "User-Agent";
}

1.1 授权认证跳转(拼接后跳转平台)

用户跳转系统,需要携带授权认证标记。SDK默认提供的标记是?oauth=1,首页地址添加该标记,会认为需要从组织授权与审计平台进行免密登录,此时需要拼接浏览器重定向地址

  • 请求地址:{platform-url}/login

  • 请求方式:浏览器 GET

  • 请求参数:

  • 参数名中文名描述
    response_type响应类型必需,约定认证的响应类型,此处固定为code
    client_id客户端id必需,在平台申请的系统id,特殊字符需要转义
    scope作用域必需,约定的作用域,固定为client
    state状态值必需,安全随机码,全流程携带,自行生成
    redirect_uri回调地址必需,认证后跳转的目的地,请参考下面的生成逻辑

    请求示例:

    GET http://220.194.160.6:8088/login?response_type=code&client_id=dataManager&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Foauth%2Fcallback%3Fredirect%3Dhttp%253A%252F%252Flocalhost%253A3000%252F%253F&scope=client&state=secret368944

运转流程

  1. 用户首次访问到认证页面,需要输入组织授权的账号密码登录,登录后会自动跳转;如果已经登录,会直接跳转
  2. 服务器会处理url参数,生成授权码code,并将statecode拼接到回调地址redirect_uri的后面,跳回原系统

redirect_uri生成逻辑

redirect_uri必须携带授权回调地址,授权回调地址由回调处理地址原访问地址组成,规则如下:

{local-url}/oauth/callback?redirect=[转义后的原访问地址]。其中redirect参数需要在最终认证流程完成后跳转过去。详细请参考下节。

1.2 授权回调地址(由平台调用)

服务端会处理认证请求携带的url参数,生成仅可单次使用的授权码(Authorization Code),该授权码需要通过重定向的方法回调到原系统,这个回调的地址称为授权回调地址。上个小节已经简单描述了该地址的生成规则,这里详细描述一下回调到该地址需要做哪些操作,以及详细的传入参数等。

  • 请求地址:{local-url}/oauth/callback

  • 请求方式:服务器发送的浏览器 302 重定向

  • 请求参数:

  • 参数名中文名描述
    code授权码由服务器发放的授权码,仅可使用一次
    state随机状态码最初生成的状态码,由服务器回传
    redirect成功回调地址生成回调地址时携带的原访问地址,原样回传

    请求示例:

    GET http://localhost:3000/oauth/callback?redirect=http%3A%2F%2Flocalhost%3A3000%2F%3F&code=Xdxfa0&state=secret523440

需要处理的逻辑

回调地址可以是一个endpoint,也可以是一个filter。请参考序章的流程图,完成由“第三方系统”完成的工作。需要后端处理传入的参数,调用获取token接口,查询用户信息,筛选关联信息,转换登录态,最终取得redirect参数,跳转回最初访问地址。

1.3 获取access_token(系统调用平台)

该接口适用于所有的需要获取token的场景。在本次对接中,包含三个场景:

(1)获取client的access_token(系统对接凭据token)

(2)获取用户的access_token(平台用户凭据token)

(3)刷新用户的access_token(平台用户凭据token)

对于三种场景,使用的token模式不同。

java
public interface OAuth2GrantType {

    // 授权码模式,用于用户access_token
    String AUTHORIZATION_CODE = "authorization_code";

    // 客户端凭据模式,用户系统对接access_token
    String CLIENT_CREDENTIALS = "client_credentials";
  
    // 刷新token
    String REFRESH_TOKEN = "refresh_token";
}
  • 请求地址:{server-url}/api/login/oauth/token

  • 请求类型:POST

  • 请求头:

  • 头部名称头部描述示例
    Content-Type内容类型,支持标准的表单类型,必需application/x-www-form-urlencoded

| Authorization | 认证凭据,支持Basic和Bearer的令牌。 | 如下: |

basic认证方式,使用clientId:clientSecret进行base64编码:

Basic ZGF0YU1hbmFnZXI6JDEkUy9pWTNjOHMkZzJRVXFqZElIa3RNNWFHenZLMEtIMQ==

参考实现:

java
request.addHeader(OAuthConstants.HEADER, OAuthConstants.BASIC + ' '
                  + base64Encoder.encodeToString(
                    String.format("%s:%s", clientId, clientSecret).getBytes(Charset.forName("UTF-8"))));
  • 请求参数:无

  • 请求体:

    参数名称参数描述示例
    code平台发放的授权码(仅授权码模式需要)t3rCbp
    redirect_uri授权回调地址(仅授权码模式需要)同1.1的redirect_uri
    refresh_token之前请求得到的刷新token(仅刷新token需要)见小节1.3.2
    grant_type权限授予类型,参考OAuth2GrantTypeauthorization_code
    scope作用于,固定为clientclient
  • 响应体:

    变量名描述示例
    access_token必有,合法的令牌见响应示例
    token_type令牌类型,默认bearerbearer
    expires_in过期时间,时间间隔129748
    scope作用于,默认clientclient
    jtijwt的idd2d3b304-8189-47f3-b6f1-f454488f38f0
    refresh_token刷新令牌(仅用户),可以用于刷新access_token见响应示例
    is_admin是否拥有管理员角色(仅用户)false
  • 请求示例:

    # 获取client token
    POST http://220.194.160.6:8088/api/login/oauth/token
    -------------header start-------------------
    Authorization: Basic ZGF0YU1hbmFnZXI6JDEkUy9pWTNjOHMkZzJRVXFqZElIa3RNNWFHenZLMEtIMQ==
    Content-Type: application/x-www-form-urlencoded
    -------------header end---------------------
    -------------payload start------------------
    scope=client&grant_type=client_credentials
    -------------payload end--------------------
    # 获取用户token
    POST http://220.194.160.6:8088/api/login/oauth/token
    -------------header start-------------------
    Authorization: Basic ZGF0YU1hbmFnZXI6JDEkUy9pWTNjOHMkZzJRVXFqZElIa3RNNWFHenZLMEtIMQ==
    Content-Type: application/x-www-form-urlencoded
    -------------header end---------------------
    -------------payload start------------------
    code=t3rCbp&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Foauth%2Fcallback%3Fredirect%3Dhttp%253A%252F%252Flocalhost%253A8080%252F%253F&scope=client&grant_type=authorization_code
    -------------payload end--------------------
  • 响应示例

    json
    // client token 响应示例
    {
    	"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6WyJjbGllbnQiXSwiZXhwIjoxNjA4Nzc3ODUzLCJqdGkiOiJkMmQzYjMwNC04MTg5LTQ3ZjMtYjZmMS1mNDU0NDg4ZjM4ZjAiLCJjbGllbnRfaWQiOiJ0ZXN0In0.VXa8ksq9eObFA4Cov5PPxgaLSOejywqPgFOjTWUT-yoflKuGNyMe45X--4T1txwW0zTqbe9OF8lDHeUzVb5IdE0kAPkZ16cj3a4PGAB0_O9d6JaM0mLu2NL-O6woFMGpN8rwfSHR00KJem6ZDFyCy3o8FSopOiMMG7FD6nTfatO6bZtKOX66Oe5tv68NAU9LHMUZUkCTi3FZa3zPfCByr7tWmh3tuKycdhw6QR_orqSsAnPKlfsbaTCY7yAYDtFuYUccypbtEHoxinMuoaRWndcDfzOLxzhjXBHakhK9AKLiJr3uyyHTkq_p5DtxQU2u8SyA9QdCaA5IevFpcN-gOQ",
    	"token_type": "bearer",
    	"expires_in": 41309,
    	"scope": "client",
    	"jti": "d2d3b304-8189-47f3-b6f1-f454488f38f0"
    }
    // user token 响应示例
    {
    	"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc19hZG1pbiI6ZmFsc2UsInVzZXJfbmFtZSI6InRlc3QiLCJzY29wZSI6WyJjbGllbnQiXSwiZXhwIjoxNjA4ODY2ODc1LCJhdXRob3JpdGllcyI6WyJjc3l5YiJdLCJqdGkiOiIzOGUwZTJhYi0yZGEyLTQ1MWQtOGQzMC1iYmUyZjdjODA5YjMiLCJjbGllbnRfaWQiOiJ0ZXN0In0.aivkqjYtWnT3itPhc7tA70hHO1y7HZmpZAbqT9LG2pUIZ0X7x_f4xntbp3lrpB2h2dsmWWV6limBUybK13TyXxC8dQ3XdpSUJmQwq3PNdaI1YlW-2jYLHUPef1Bv2DSR3rtZTaeMtT5poP0MiKNtD4XSxpWC0wO_48e0UCkaPoYWfl5RKBhXoXNalojcmBwEFJvppnx-hY87GbLt7DO1T2fZSLRq-SI3ZW202DIVjza8RzOXw0XOR-AsW3KqzpgHfAdRHqLMhFFw3Ps8GRtRYnCYSNllncxJ5x4cpDjtSNr4l_09GDulJ15VZwcMEdJsfIQZ1FI7LiyShTpw1gN5qA",
    	"token_type": "bearer",
    	"refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc19hZG1pbiI6ZmFsc2UsInVzZXJfbmFtZSI6InRlc3QiLCJzY29wZSI6WyJjbGllbnQiXSwiYXRpIjoiMzhlMGUyYWItMmRhMi00NTFkLThkMzAtYmJlMmY3YzgwOWIzIiwiZXhwIjoxNjIyNDI2Njk0LCJhdXRob3JpdGllcyI6WyJjc3l5YiJdLCJqdGkiOiI2ODUyZTgyMi04ZDcwLTRmYTctOGEzOS0zYjc4YTE1MDIwYzYiLCJjbGllbnRfaWQiOiJ0ZXN0In0.tzPM3APsxTCRomZwlbsw8s2uw2Xtcb8luoR6et60zR87OVtlGs36jy-GyVyIaTxhjzgfsVMXMvihKLTm1-Rxs3t2srX2YDwJH2-jPIMOw4rPC7WlAj7NE0QGK7rKYjmt6OoKPh3m8I_BfMDyLvqRCImVII8UKvJelwcGAp1EtsfbrZE-WcKjwM3uCjwnsnt3YMEM7QduClx52-Sm1sVxVzavgZdCwRbKUz8IrdfBX92k9dtzK6G_MXeDVcRgbmCOEWHUdeUqLmfGFy_mz6VUIpSiut9VwYB5gNzPv234SgaTljORtGcTfr-zuQGJnIAoL7h9nCG-Hvj6xzdrHTFvBg",
    	"expires_in": 129748,
    	"scope": "client",
    	"is_admin": false,
    	"jti": "38e0e2ab-2da2-451d-8d30-bbe2f7c809b3"
    }

需要注意的是,client_credentials的token有效期较长,强烈建议缓存该token,token过期,可以使用refresh_token进行token刷新操作。对于token的操作,还包括以下操作,请根据需要调用:

1.3.1 检查token(不需要携带身份凭据)

该接口可以检查用户token或者系统token。

  • 请求地址:{server-url}/api/login/oauth/check_token

  • 请求方法:GET

  • 请求参数: token 要检查的bearer token

  • 响应参数:

    变量名变量说明示例
    is_admin是否是管理员false
    user_name平台用户名test
    scope作用于列表["client"]
    active是否可用,false为过期true
    exp过期的时间戳(秒)1608866875
    authorities拥有的权限列表["csyyb"]
    jtijwt的id38e0e2ab-2da2-451d-8d30-bbe2f7c809b3
    client_id所属客户端idtest
  • 请求示例

    GET http://220.194.160.6:8088/api/login/oauth/check_token?token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc19hZG1pbiI6ZmFsc2UsInVzZXJfbmFtZSI6InRlc3QiLCJzY29wZSI6WyJjbGllbnQiXSwiZXhwIjoxNjA4ODY2ODc1LCJhdXRob3JpdGllcyI6WyJjc3l5YiJdLCJqdGkiOiIzOGUwZTJhYi0yZGEyLTQ1MWQtOGQzMC1iYmUyZjdjODA5YjMiLCJjbGllbnRfaWQiOiJ0ZXN0In0.aivkqjYtWnT3itPhc7tA70hHO1y7HZmpZAbqT9LG2pUIZ0X7x_f4xntbp3lrpB2h2dsmWWV6limBUybK13TyXxC8dQ3XdpSUJmQwq3PNdaI1YlW-2jYLHUPef1Bv2DSR3rtZTaeMtT5poP0MiKNtD4XSxpWC0wO_48e0UCkaPoYWfl5RKBhXoXNalojcmBwEFJvppnx-hY87GbLt7DO1T2fZSLRq-SI3ZW202DIVjza8RzOXw0XOR-AsW3KqzpgHfAdRHqLMhFFw3Ps8GRtRYnCYSNllncxJ5x4cpDjtSNr4l_09GDulJ15VZwcMEdJsfIQZ1FI7LiyShTpw1gN5qA
  • 响应示例

    json
    {
    	"is_admin": false,
    	"user_name": "test",
    	"scope": ["client"],
    	"active": true,
    	"exp": 1608866875,
    	"authorities": ["csyyb"],
    	"jti": "38e0e2ab-2da2-451d-8d30-bbe2f7c809b3",
    	"client_id": "test"
    }

1.3.2 刷新token

该接口可以通过refresh_token刷新access_token。一般用于检查access_token失效后,尝试快速获得新的可用access_token。

刷新token请参考1.3章节,设置grant_type为refresh_token,并附带refresh_token即可。

  • 请求示例:
POST http://220.194.160.6:8088/api/login/oauth/token
-------------header start-------------------
Authorization: Basic ZGF0YU1hbmFnZXI6JDEkUy9pWTNjOHMkZzJRVXFqZElIa3RNNWFHenZLMEtIMQ==
Content-Type: application/x-www-form-urlencoded
-------------header end---------------------
-------------payload start------------------
refresh_token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc19hZG1pbiI6ZmFsc2UsInVzZXJfbmFtZSI6InRlc3QiLCJzY29wZSI6WyJjbGllbnQiXSwiYXRpIjoiYTM4MjExNTctMmUxYS00ZTBiLTkyNGMtYjk2MmE4ODU3YjljIiwiZXhwIjoxNjIyNDI2Njk0LCJhdXRob3JpdGllcyI6WyJjc3l5YiJdLCJqdGkiOiI2ODUyZTgyMi04ZDcwLTRmYTctOGEzOS0zYjc4YTE1MDIwYzYiLCJjbGllbnRfaWQiOiJ0ZXN0In0.IM1r_8PrqxgFiXuwkr0Fu-RKdB_ye-x7EykT-s29ki3UW8yGUpfvIOqLqB3Ku1CHbcNwYUbXriEB3bzzih0rAZZZkU1oIzZ9tj-MptqKWNK28C7R3CCywR6rU2tPRazbkMKS0f1jrLhvOL7Qhvj0qzyz7JMC7EIrzX1_EH--TBBw1b39us2WijRiGzWIH0Jx4p-elAkuJZqBA5rgR8ZpD0JAWeCf_UiW9iRjJCHDQCw1NDJfP3gKWj8nqUmXGRaFji6fr1DhsjTs-07VxPyCwPHPI_C8voyD7iShjdm1C_StiZmBO7jwsfR2Q2lGDIAvE2a2SPvmWnGKhIyxHoxCdQ&scope=client&grant_type=refresh_token
-------------payload end--------------------
  • 响应示例:

    json
    {
    	"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc19hZG1pbiI6ZmFsc2UsInVzZXJfbmFtZSI6InRlc3QiLCJzY29wZSI6WyJjbGllbnQiXSwiZXhwIjoxNjA4ODY2ODc1LCJhdXRob3JpdGllcyI6WyJjc3l5YiJdLCJqdGkiOiIzOGUwZTJhYi0yZGEyLTQ1MWQtOGQzMC1iYmUyZjdjODA5YjMiLCJjbGllbnRfaWQiOiJ0ZXN0In0.aivkqjYtWnT3itPhc7tA70hHO1y7HZmpZAbqT9LG2pUIZ0X7x_f4xntbp3lrpB2h2dsmWWV6limBUybK13TyXxC8dQ3XdpSUJmQwq3PNdaI1YlW-2jYLHUPef1Bv2DSR3rtZTaeMtT5poP0MiKNtD4XSxpWC0wO_48e0UCkaPoYWfl5RKBhXoXNalojcmBwEFJvppnx-hY87GbLt7DO1T2fZSLRq-SI3ZW202DIVjza8RzOXw0XOR-AsW3KqzpgHfAdRHqLMhFFw3Ps8GRtRYnCYSNllncxJ5x4cpDjtSNr4l_09GDulJ15VZwcMEdJsfIQZ1FI7LiyShTpw1gN5qA",
    	"token_type": "bearer",
    	"refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc19hZG1pbiI6ZmFsc2UsInVzZXJfbmFtZSI6InRlc3QiLCJzY29wZSI6WyJjbGllbnQiXSwiYXRpIjoiMzhlMGUyYWItMmRhMi00NTFkLThkMzAtYmJlMmY3YzgwOWIzIiwiZXhwIjoxNjIyNDI2Njk0LCJhdXRob3JpdGllcyI6WyJjc3l5YiJdLCJqdGkiOiI2ODUyZTgyMi04ZDcwLTRmYTctOGEzOS0zYjc4YTE1MDIwYzYiLCJjbGllbnRfaWQiOiJ0ZXN0In0.tzPM3APsxTCRomZwlbsw8s2uw2Xtcb8luoR6et60zR87OVtlGs36jy-GyVyIaTxhjzgfsVMXMvihKLTm1-Rxs3t2srX2YDwJH2-jPIMOw4rPC7WlAj7NE0QGK7rKYjmt6OoKPh3m8I_BfMDyLvqRCImVII8UKvJelwcGAp1EtsfbrZE-WcKjwM3uCjwnsnt3YMEM7QduClx52-Sm1sVxVzavgZdCwRbKUz8IrdfBX92k9dtzK6G_MXeDVcRgbmCOEWHUdeUqLmfGFy_mz6VUIpSiut9VwYB5gNzPv234SgaTljORtGcTfr-zuQGJnIAoL7h9nCG-Hvj6xzdrHTFvBg",
    	"expires_in": 129748,
    	"scope": "client",
    	"is_admin": false,
    	"jti": "38e0e2ab-2da2-451d-8d30-bbe2f7c809b3"
    }

1.3.3 撤销token

用户如果需要释放token,在退出系统时可以调用该接口,通知平台将该token放入黑名单。

  • 请求地址:{server-url}/logout

  • 请求方式:POST

  • 请求参数: 无

  • 请求头:

    **内容类型:**Content-Type: application/x-www-form-urlencoded

    **client认证头:**Authorization: Basic Base64({clientId}:{clientSecret})

  • 请求体:token: 【需要撤回的token】

  • 响应体:空

  • 请求示例:

    POST http://220.194.160.6:8088/logout
    # header示例省略
    ------------------body----------------
    token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc19hZG1pbiI6ZmFsc2UsInVzZXJfbmFtZSI6InRlc3QiLCJzY29wZSI6WyJjbGllbnQiXSwiZXhwIjoxNjA4OTk3NzM2LCJhdXRob3JpdGllcyI6WyJjc3l5YiJdLCJqdGkiOiJhMzgyMTE1Ny0yZTFhLTRlMGItOTI0Yy1iOTYyYTg4NTdiOWMiLCJjbGllbnRfaWQiOiJ0ZXN0In0.h_HcuDIJLdg-s-A9cbJE4Z2xLd0a2pIdTeZnyhauowKLSZBNWSSKMrpsL4cBgr5wN8y9_fPYeAjZHM-8xbnEMJQiWzCSd9A-w62uby-_w6VqBEq8TW-4Q4BapUo8NlVR8yaq3cqoBzUniPaI2Nr9tc656dHrUB8Iaycw7M2yE0KFtwePK2JFylYnriLG1WNoXQbUUtbN5ABe-0iFB9f6TyGO156UtrGVMIjoTzQ3cjMjfFvyyy4mTz0FeX0puqBtrk4RCkDeBC4E4g6nqnRkuNXMt-VBp0QVqm-J9mntXlJW7_H4yhm3sYvb-Re_W8GUTc8oVhuFPI7kMPsHK5kTzQ
  • 响应示例:

    json
    {}

    撤回token返回200状态码即为撤回成功,否则为失败。

1.4 获取用户信息

获取到用户的access_token后,可以通过access_token获取用户信息,用户信息包含平台信息,以及关联的第三方系统信息。需要从用户的关联信息中找到client_id为本系统的信息,取得outerId。该outerId为本系统的用户id,可以直接通过查询精确获得用户实体信息。

  • 请求地址:{server-url}/api/login/user-info

  • 请求方式:GET

  • 请求参数:无

  • 请求头:

    Authorization: Bearer {access_token} 需要附带access_token以访问

  • 请求体:无

  • 响应体:请直接参考响应示例

  • 请求示例

    GET http://220.194.160.6:8088/api/login/user-info
  • 响应示例

    json
    {
    	"id": "5fc6f274fc6f0c8a6ff88f6f",  // 平台用户id
    	"name": "外部系统测试用户",           // 平台用户名
    	"userType": "NORMAL",              // 平台用户类型
    	"userStatus": "NORMAL",            // 平台用户状态
    	"phone": "12312312312",            // 平台用户手机
    	"username": "test",                // 平台用户账号
    	"enable": true,                    // 平台用户启用状态
    	"linkedUsers": [{                  // 关联的系统用户
    		"id": "5fc747919656d7fa86592e3e",      // 平台存储的系统用户id
    		"name": "管理员",                       // 用户姓名
    		"createTime": "2020-11-26 17:04:28",   // 创建时间
    		"modifyTime": "2020-12-14 15:48:45",   // 修改时间
    		"creator": "5fb4ed1da400c70ec060b556", // 创建人
    		"modifier": "5e9038c3c5502423f7357534",// 修改人
    		"delete": false,                       // 删除标记
    		"outerId": "2",                        // 系统本地用户id,查询本地系统用户用
    		"username": "wangbiao",                // 系统用户名
    		"birthDay": "2020-11-26",              // 生日
    		"email": "sn93@qq.com",                // 电子邮件
    		"gender": "MALE",                      // 性别
    		"organization": [],                    // 组织或部门
    		"phone": "13835681234",                // 手机号
    		"idCardNo": "142422199300000111",      // 身份证号
    		"clientId": "dimp"                     // 所属系统id,需要您自己在这些关联信息中筛选clientId为当前系统的用户
    	}, {
    		"id": "5fcd8c5be5ce84f860763908",
    		"name": "admin",
    		"createTime": "2020-12-07 09:58:51",
    		"modifyTime": "2020-12-23 18:35:09",
    		"creator": "5e9038c3c5502423f7357534",
    		"modifier": "5e9038c3c5502423f7357534",
    		"delete": false,
    		"outerId": "1",
    		"username": "admin",
    		"organization": [],
    		"phone": "13315231231",
    		"clientId": "dataManager"
    	}],
    	"organizations": [{
    		"id": "5fc6eceefc6f0c8a6ff88f56",
    		"code": "csyyb",
    		"name": "测试运营部",
    		"createTime": "2020-12-02 09:25:02",
    		"modifyTime": "2020-12-02 09:25:02",
    		"creator": "5e9038c3c5502423f7357534",
    		"modifier": "5e9038c3c5502423f7357534",
    		"delete": false,
    		"pos": 262140.0,
    		"parentId": "5fc6ecbffc6f0c8a6ff88f53",
    		"depth": 2,
    		"attribute": "NORMAL_DEPARTMENT"
    	}],
    	"authorities": [{
    		"authority": "csyyb"
    	}],
    	"enabled": true,
    	"accountNonExpired": true,
    	"accountNonLocked": true,
    	"credentialsNonExpired": true
    }

1.5 用户同步接口

用户同步存在两个阶段。为了方便调试和快速接入,项目启动完成后需要缺省调用一次。该接口发送的用户为本系统用户,且不会和平台用户有任何逻辑交叉,只通过双方内部id做一对一关联绑定。

  • 请求地址:{server-url}/api/data/external-users/sync

  • 请求方式:PUT

  • 请求参数:无

  • 请求头:

    变量名变量描述示例
    Authorizationclient的鉴权凭据,支持Basic和BearerBearer {access_token} | Basic Base64({CI}:{CS})
    Content-Type内容类型,支持json的数据application/json
  • 请求体:

    请求体支持JSON Array,可以同步用户列表。用户实体的模型如下,可按需同步

    变量名变量描述示例
    code可选,系统用户编号或英文名0001
    name必需,用户中文名张三
    outerId必需,用户在本系统的唯一标识UUID|int id
    username必需,用户账号,用于系统辨别zhang3
    birthDay可选,用户生日,格式yyyy-MM-dd1981-03-11
    email可选,用户邮箱,格式{name}@test@unicom.com
    gender可选,标记用户性别用于区分,请注意枚举值MALE|FEMALE
    organization可选,用户所属组织或部门,支持多个["综合部", "人力资源部"]
    phone可选,手机号,用于确定唯一用户18355551111
    idCardNo可选,身份证号,用于确定唯一用户18位中华人民共和国居民身份证号
    comment可选,对用户进行描述,便于管理员进行识别该用户系硕士生毕业,已入职三年...
  • 响应体

    变量名变量描述示例
    code状态码,0为成功,其他为失败0
    msg发生异常情况会给出具体的错误信息请求成功
    success系统缺省返回的成功标记,可以快速判断成功与否true
    data具体的响应数据,请参考具体内部数据结构{}

    data内部响应结构

    变量名变量描述示例
    modifiedCount修改的记录数1
    matchedCount匹配到的记录数1
    insertedCount新增的记录数0
    upserts新增修改的记录id列表abcd-erty-bsax
    modifiedCountAvailable已经修改的数量是否可用true
    deletedCount删除的记录数0
  • 请求示例

    PUT http://220.194.160.6:8088/api/data/external-users/sync
    --------------------header--------------------------------------
    Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc19hZG1pbiI6ZmFsc2UsInVzZXJfbmFtZSI6InRlc3QiLCJzY29wZSI6WyJjbGllbnQiXSwiZXhwIjoxNjA4OTk3NzM2LCJhdXRob3JpdGllcyI6WyJjc3l5YiJdLCJqdGkiOiJhMzgyMTE1Ny0yZTFhLTRlMGItOTI0Yy1iOTYyYTg4NTdiOWMiLCJjbGllbnRfaWQiOiJ0ZXN0In0.h_HcuDIJLdg-s-A9cbJE4Z2xLd0a2pIdTeZnyhauowKLSZBNWSSKMrpsL4cBgr5wN8y9_fPYeAjZHM-8xbnEMJQiWzCSd9A-w62uby-_w6VqBEq8TW-4Q4BapUo8NlVR8yaq3cqoBzUniPaI2Nr9tc656dHrUB8Iaycw7M2yE0KFtwePK2JFylYnriLG1WNoXQbUUtbN5ABe-0iFB9f6TyGO156UtrGVMIjoTzQ3cjMjfFvyyy4mTz0FeX0puqBtrk4RCkDeBC4E4g6nqnRkuNXMt-VBp0QVqm-J9mntXlJW7_H4yhm3sYvb-Re_W8GUTc8oVhuFPI7kMPsHK5kTzQ
    Content-Type: application/json
    --------------------body:application/json-----------------------
    [{                 
    		"code": "20110309",                    // 用户编号
    		"name": "管理员",                       // 用户姓名
    		"outerId": "2",                        // 系统本地用户id,查询本地系统用户用
    		"username": "wangbiao",                // 系统用户名
    		"birthDay": "2020-11-26",              // 生日
    		"email": "sn93@qq.com",                // 电子邮件
    		"gender": "MALE",                      // 性别
    		"organization": ["综合部", "人力资源部"], // 组织或部门
    		"phone": "13835681234",                // 手机号
    		"idCardNo": "142422199300000111",      // 身份证号
    }]
  • 响应示例

    json
    {
    	"data": {
    		"modifiedCount": 1,
    		"matchedCount": 1,
    		"insertedCount": 0,
    		"upserts": [],
    		"modifiedCountAvailable": true,
    		"deletedCount": 0
    	},
    	"code": "0",
    	"msg": "请求成功",
    	"success": true
    }

用户同步时机

  1. 项目启动后需要首次同步一次用户
  2. 用户新增,修改,删除操作时,需要通知服务器更新用户列表,进行差量同步。