全部产品

边缘应用OAuth免登对接

更新时间:2020-03-05 19:09:37

1.边缘应用OAuth免登介绍

本章主要介绍部署在边缘集群托管的应用,实现免登及用户信息获取相关流程。

1.1 OAuth免登调用流程

  1. 系统应用环境变量中获取访问域名。System.getenv(“iot.hosting.api.domain”)。
  2. 应用跳转IoT oauth验证地址,同时携带认证后跳转的callback地址。
  3. IoT认证后,携带授权码oauthcode跳转第2步callback的地址。
  4. 应用获取到oauthcode后可以换取accesscode,并通过accesscode获取到用户的完整信息。1

2.实操效果展示

2.1 部署组件

单击组件管理>访问入口 复制IP+端口号,打开新的浏览器页面进行访问,如下图所示:
2

2.2 登录边缘控制台。

使用“超级账户iotedgeadmin”登录“集群控制台”,用户名与密码一致,首次登录强制修改密码,此连接为内网地址,请保证电脑可以正常连接至内网,如下图所示:
3

2.3 查看部署应用

登录成功后,可单击部署应用的应用卡片,进入应用详情,如下图所示:
4

2.4 点击应用进行免登

点击部署的应用,直接跳转到应用内部,验证免登,如下图所示:
5

3.开发API

3.1 获取应用入口地址

接口描述:

授权类型 APPSIGN
协议 HTTP
请求方法 get
域名(环境变量中获取) System.getenv(“iot.hosting.api.domain”)
路径 /api/console/app/get

入参说明

入参名称 数据类型 是否必须 入参示例 入参描述
appKey 字符串 213124133 appkey
port int 80443 请求的服务端口

出参列表

出参名称 数据类型 出参描述
code 整形 响应码, 200: 成功
message 字符串 错误消息
localizedMsg 字符串 本地语言错误消息
data 长整型 响应结果 返回为app的相关应用url

请求拼接示例

  1. http://30.42.82.42:32187/api/console/app/get?appKey=28135051

请求示例

  1. /**
  2. * 获取环境变量和回调的url
  3. * @return
  4. */
  5. //iot.hosting.api.schema----是请求协议格式http
  6. private static final String API_GATEWAY_SCHEMA = System.getenv("iot.hosting.api.schema");
  7. //iot.hosting.api.domain--是跳转路径的回调ip地址
  8. private static final String API_GATEWAY_DOMAIN = System.getenv("iot.hosting.api.domain");
  9. //iot.hosting.api.port----是请求端口
  10. private static final String API_GATEWAY_SCHEMA = System.getenv("iot.hosting.api.port");
  11. // iot.hosting.appKey----是请求的appkey
  12. private static final String API_GATEWAY_SCHEMA = System.getenv(" iot.hosting.appKey");
  13. //PATH_APP_GET是请求应用app的响应路径
  14. private static final String PATH_APP_GET = "/api/console/app/get";
  15. @Override
  16. public String getAppIndex() {
  17. RequestBuilder builder = RequestBuilder.create(METHOD_GET);
  18. Map<String, String> queryParams = Maps.newHashMap();
  19. queryParams.put(PARAM_APP_KEY, appKey);
  20. builder.setUri(HttpUtils.buildUrl(schema, apiGatewayDomain, apiGatewayPort, PATH_APP_GET, queryParams));
  21. IoTxResult<AppDTO> result = httpProxy.invoke(
  22. (HttpRequestBase) builder.build(),
  23. new TypeReference<IoTxResult<AppDTO>>() {
  24. }
  25. );
  26. logger.info("path={}; params={}; result={}", PATH_APP_GET, JSON.toJSONString(queryParams), JSON.toJSONString(result));
  27. Assert.assertSuccess(result);
  28. AppDTO app = result.getData();
  29. return app.getLoginUrl();
  30. }

返回结果示例 JSON

  1. {
  2. {
  3. "code": 200,
  4. "data": {
  5. "aliyunPk": "101248722030****",
  6. "appKey": "28135***",
  7. "appMeta": {
  8. "logoUrl": "http://192.168.11.130:32628/index/28135***",
  9. "name": "oauth2边缘托管",
  10. "subVersionId": "1.0",
  11. "uuid": "937aaa0284864396b54ecadb0d1629c6",
  12. "versionUuid": "9ff097f16d8347e6abfcaec0cd14ce56"
  13. },
  14. "appSecret": "NGNiOWQyYzI4MGVhOWNlYmNhOTdmMDIyNTg2MzlhY2Q=",
  15. "clusterId": "bbeba04d880d49dc80bf83632619341c",
  16. "configName": "oauth2边缘托管",
  17. "configUuid": "a7b996cd6ab04b7fb3a54abbc81b88ea",
  18. "configVersionUuid": "8e43f4d96bef4a289ad9f9af079df8bb",
  19. "loginUrl": "http://192.168.11.130:30313/index",//-----应用登录url
  20. "name": "Oauth2演示",
  21. "oauth": {
  22. "path": "/index",
  23. "port": 8080,
  24. "protocol": "",
  25. "serviceName": "edge",
  26. "serviceUuid": ""
  27. },
  28. "type": "GENERAL_APP",
  29. "uuid": "731082ac0c444053bad624ec915b8a6f"
  30. },
  31. "message": "success"
  32. }
  33. }

3.2 获取API网关地址

接口描述

授权类型 APPSIGN
协议 HTTP
请求方法 get
域名(环境变量中获取) System.getenv(“iot.hosting.api.domain”)
路径 /api/console/host/account

入参说明

入参名称 数据类型 是否必须 入参示例 入参描述
chema 字符串 http 请求协议
ports int 80443 请求的服务端口
url 字符型 /api/console/host/account 请求url
host 字符型 30.42.82.42:32187 请求host

出参列表

出参名称 数据类型 出参描述
code 整形 响应码, 200: 成功
message 字符串 错误消息
localizedMsg 字符串 本地语言错误消息
data 长整型 响应结果

请求拼接示例

  1. http://30.42.82.42:32187/api/console/host/account

请求示例

  1. /**
  2. *
  3. * /api/console/host/account
  4. * @param path
  5. * @return
  6. */
  7. @Override
  8. public URI getURI(String path) {
  9. RequestBuilder builder = RequestBuilder.create(METHOD_GET);
  10. Map<String, String> queryParams = Maps.newHashMap();
  11. builder.setUri(HttpUtils.buildUrl(schema, apiGatewayDomain, apiGatewayPort, path, queryParams));
  12. logger.info("RequestBuilder请求url");
  13. IoTxResult<String> result = httpProxy.invoke(
  14. (HttpRequestBase) builder.build(),
  15. new TypeReference<IoTxResult<String>>() {
  16. }
  17. );
  18. logger.info("path={}; params={}; result={}", path, JSON.toJSONString(queryParams), JSON.toJSONString(result));
  19. Assert.assertSuccess(result);
  20. try {
  21. return new URI(result.getData());
  22. } catch (URISyntaxException e) {
  23. throw new RuntimeException(e);
  24. }
  25. }

返回结果示例 JSON

  1. {
  2. "code": 200,
  3. "data": {
  4. "oauth": {
  5. "path": "/index",
  6. "port": 32187,
  7. "host":30.42.82.42
  8. "protocol": "",
  9. "serviceName": "edge",
  10. "serviceUuid": ""
  11. },
  12. "type": "GENERAL_APP",
  13. "uuid": "731082ac0c444053bad624ec915b8a6f"
  14. },
  15. "message": "success"
  16. }

3.3 发起免登验证

接口描述

授权类型 APPSIGN
协议 HTTP
请求方法 get
域名(环境变量中获取) System.getenv(“iot.hosting.api.domain”)
路径 /oauth2/auth

入参说明

入参名称 数据类型 是否必须 入参示例 入参描述
client_id String 28135051 应用的appkey
redirect_uri String http://30.42.82.42:32187/index OAuth认证通过后的重定向应用的URI,包含完整的域名
response_type String code 返回类型。根据OAuth 2.0标准,目前支持设置此参数的取值为code
state String 28135051 应用的appkey携带项
scope String 空格分隔的OAuth范围列表。如不指定此参数取值,则默认为应用注册的全部OAuth范围,加上scopid

出参列表

出参名称 数据类型 出参描述
code 整形 响应码, 200: 成功
message 字符串 错误消息
localizedMsg 字符串 本地语言错误消息
data 长整型 响应结果

请求拼接示例

  1. http://30.42.82.42:32187/oauth2/auth?
  2. redirect_uri=http://30.42.82.42:32187/index&
  3. client_id=28135051&state=28135051&
  4. response_type=code

请求示例

  1. /**
  2. *获取免登url和code
  3. * @param appKey
  4. * @param redirectUri
  5. * @return
  6. */
  7. public String getLoginRedirectUrl(String appKey, String redirectUri) {
  8. Map<String, String> queryParams = Maps.newHashMap();
  9. queryParams.put(PARAM_CLIENT_ID, appKey);
  10. queryParams.put(PARAM_REDIRECT_URI, redirectUri);
  11. queryParams.put(PARAM_RESPONSE_TYPE, "code");
  12. URI accountUri = getAccountUri();
  13. return HttpUtils.buildUrl(
  14. schema,
  15. accountUri.getHost(),
  16. accountUri.getPort(),
  17. PATH_LOGIN,
  18. queryParams).toASCIIString();
  19. }

返回结果示例 JSON

  1. http://30.42.82.42:32187/index?code=64a67ee15534defea7ad0d0535189b24&state=28135051

3.4 换取accessToken

接口描述

授权类型 ANONYMOUS
协议 HTTP
请求方法 post
域名(环境变量中获取) System.getenv(“iot.hosting.api.domain”)
路径 /user/oauth2/token/get

入参说明

入参名称 数据类型 是否必须 入参描述
code 字符串 初始请求中获取的授权码
grant_type 字符串 根据OAuth 2.0标准, 取值为authorization_code
redirect_uri 字符型 初始authorization请求中设置的redirect_uri参数
client_id 字符型 应用的appkey

出参列表

出参名称 数据类型 出参描述
code 整形 响应码, 200: 成功
message 字符串 错误消息
localizedMsg 字符串 本地语言错误消息
data 长整型 响应结果

请求示例

  1. /**
  2. * 根据code获取到token
  3. * @param appKey
  4. * @param oauthCode
  5. * @return
  6. */
  7. public String getAccessTokenByOauthCode(String appKey, String oauthCode) {
  8. RequestBuilder builder = RequestBuilder.create(METHOD_GET);
  9. Map<String, String> queryParams = Maps.newHashMap();
  10. queryParams.put(PARAM_CODE, oauthCode);
  11. queryParams.put(PARAM_GRANT_TYPE, "authorization_code");
  12. queryParams.put(PARAM_CLIENT_ID, appKey);
  13. URI accountUri = getAccountUri();
  14. builder.setUri(HttpUtils.buildUrl(accountUri.getScheme(), accountUri.getHost(), accountUri.getPort(), PATH_GET_ACCESS_TOKEN_BY_OAUTH_CODE, queryParams));
  15. IoTxResult<AccessTokenDTO> result = httpProxy.invoke(
  16. (HttpRequestBase) builder.build(),
  17. new TypeReference<IoTxResult<AccessTokenDTO>>() {
  18. }
  19. );
  20. PROXY_LOGGER.info("path={}; params={}; result={}", PATH_GET_ACCESS_TOKEN_BY_OAUTH_CODE, JSON.toJSONString(queryParams), JSON.toJSONString(result));
  21. Assert.assertSuccess(result);
  22. AccessTokenDTO accessTokenDTO = result.getData();
  23. Assert.assertNotNull(accessTokenDTO, "get accessToken failed");
  24. return accessTokenDTO.getAccessToken();
  25. }

返回结果示例 JSON

  1. {
  2. "code": 200,
  3. "data": {
  4. "access_token": "agasdfagdsafasdf",
  5. "expired_time": 21232,
  6. "refresh_token": "asdgadgasfadsaf",
  7. "token_type": "Bearer",
  8. "open_id": "gasdfasdfasdf"
  9. },
  10. "id": "246da69e-40ad-4f44-955e-ac880f9867d7"
  11. }

3.5 获取用户信息

接口描述

授权类型 ANONYMOUS
协议 HTTP
请求方法 post
域名(环境变量中获取) System.getenv(“iot.hosting.api.domain”)
路径 /user/oauth2/userinfo/get

入参说明

入参名称 数据类型 是否必须 入参示例 入参描述
access_token String 3123qwqrqwq 访问令牌

出参列表

出参名称 数据类型 出参描述
code 整形 响应码, 200: 成功
message 字符串 错误消息
localizedMsg 字符串 本地语言错误消息
data 长整型 响应结果

请求示例

  1. /**
  2. * 根据token获取用户信息
  3. * @param accessToken
  4. * @return
  5. */
  6. public UserInfoDTO getUserInfoByAccessToken(String accessToken) {
  7. RequestBuilder builder = RequestBuilder.create(METHOD_GET);
  8. Map<String, String> queryParams = Maps.newHashMap();
  9. queryParams.put(PARAM_ACCESS_TOKEN, accessToken);
  10. URI accountUri = getAccountUri();
  11. builder.setUri(HttpUtils.buildUrl(accountUri.getScheme(), accountUri.getHost(), accountUri.getPort(), PATH_GET_USER_INFO_BY_ACCESS_TOKEN, queryParams));
  12. IoTxResult<UserInfoDTO> result = httpProxy.invoke(
  13. (HttpRequestBase) builder.build(),
  14. new TypeReference<IoTxResult<UserInfoDTO>>() {
  15. }
  16. );
  17. PROXY_LOGGER.info("path={}; params={}; result={}", PATH_GET_USER_INFO_BY_ACCESS_TOKEN, JSON.toJSONString(queryParams), JSON.toJSONString(result));
  18. Assert.assertSuccess(result);
  19. UserInfoDTO userInfoDTO = result.getData();
  20. Assert.assertNotNull(userInfoDTO, "get userInfo failed");
  21. return userInfoDTO;
  22. }

返回结果示例 JSON

  1. "id": "246da69e-40ad-4f44-955e-ac880f9867d7",
  2. "code": 200,
  3. "message": null,
  4. "localizedMsg": null,
  5. "data": {
  6. "open_id": "eaef01f7bfaf0b7a95366720d58d1fd5",
  7. "name": "test",
  8. "phone": "13812345678",
  9. "tenant_open_id": "1c8c23f0adef8bd04fa166372b781f0d",
  10. "tenant_name": "test"
  11. }

3.6 Token有效性判断

接口描述

授权类型 ANONYMOUS
协议 HTTP
请求方法 post
域名(环境变量中获取) System.getenv(“iot.hosting.api.domain”)
路径 /user/oauth2/accesstoken/check

入参说明

入参名称 数据类型 是否必须 入参示例 入参描述
access_token String 3123qwqrqwq 访问令牌

出参列表

出参名称 数据类型 出参描述
code 整形 响应码, 200: 成功
message 字符串 错误消息
localizedMsg 字符串 本地语言错误消息
data 长整型 响应结果

请求示例

  1. /**
  2. * token登录有效期检查
  3. * @param token
  4. * @return
  5. */
  6. public boolean checkLogin(String token) {
  7. RequestBuilder builder = RequestBuilder.create(METHOD_GET);
  8. Map<String, String> queryParams = Maps.newHashMap();
  9. queryParams.put(PARAM_ACCESS_TOKEN, token);
  10. URI accountUri = getAccountUri();
  11. builder.setUri(HttpUtils.buildUrl(accountUri.getScheme(), accountUri.getHost(), accountUri.getPort(), PATH_LOGINCHECK, queryParams));
  12. IoTxResult<Boolean> result = httpProxy.invoke(
  13. (HttpRequestBase) builder.build(),
  14. new TypeReference<IoTxResult<Boolean>>() {
  15. }
  16. );
  17. PROXY_LOGGER.info("path={}; params={}; result={}", PATH_LOGINCHECK, JSON.toJSONString(queryParams), JSON.toJSONString(result));
  18. Assert.assertSuccess(result);
  19. return result.getData();
  20. }

返回结果示例 JSON

  1. {
  2. "code": 200,
  3. "data": {
  4. "result":true
  5. },
  6. }