提供基于iotToken的用户身份认证方案,通过和账号及用户SDK、API通道SDK的集成,完成用户身份凭证的生成和管理,以及发起API请求的用户身份的鉴权。

依赖SDK 概述
日志 基础依赖SDK,提供客户端统一日志打印,日志等级控制,分模块日志隔离等能力
AP通道 提供API通道能力,和基础环境配置信息

初始化

身份认证SDK的初始化依赖API通道的初始化和账号抽象的实现,然后再参考下面的示例代码初始化。

// 引入头文件
#import <IMSApiClient/IMSApiClient.h>
#import <IMSAccount/IMSAccountService.h>
#import <IMSAuthentication/IMSAuthentication.h>

IMSAccountService *accountService = [IMSAccountService sharedService];
// sessionProvider 需要开发者实现遵守IMSAccountProtocol协议的class 实例 
accountService.sessionProvider = (id<IMSAccountProtocol>)sessionProvider;
[IMSCredentialManager initWithAccountProtocol:accountService.sessionProvider];
IMSIoTAuthentication *iotAuthDelegate = [[IMSIoTAuthentication alloc] initWithCredentialManager:IMSCredentialManager.sharedManager];
[IMSRequestClient registerDelegate:iotAuthDelegate forAuthenticationType:IMSAuthenticationTypeIoT];
			

使用方式

  • 发送带身份认证的API请求
    // 引入头文件
    #import <IMSAuthentication/IMSIoTAuthentication.h>
    #import <IMSApiClient/IMSApiClient.h>
    
    // 构建请求
    NSString *path = @"/uc/listByAccount";
    NSString *apiVer = @"1.0.0";
    NSDictionary *params = @{};
    IMSIoTRequestBuilder *builder = [[IMSIoTRequestBuilder alloc] initWithPath:path apiVersion:apiVer params:params];
    
    // 指定身份认证类型
    [builder setAuthenticationType:IMSAuthenticationTypeIoT];
    
    //通过 IMSRequestClient 发送请求
    [IMSRequestClient asyncSendRequest:builder.build responseHandler:^(NSError * _Nullable error, IMSResponse * _Nullable response) {
        if (error) {
            //处理Error,非服务端返回的错误都通过该Error回调
        } else {
            if (response.code == 200) {
                //成功,处理response.data
            }
            else {
                //处理服务端错误
            }
        }
    }];
    					
  • API 请求的认证错误处理

    目前服务端逻辑不支持同一个账号多端登录。如果一个账号在多个设备登录,那么只有最后一个登录的账号才可以正常访问IoT服务,其他账号在发送API通道请求时则会返回认证错误(错误码为401)。另外,如果账号未登录或登录信息过期(或长时间未登录)时,也会在发送API通道请求时返回认证错误。

    通常情况下只需要处理API请求的错误即可。

    [IMSRequestClient asyncSendRequest:builder.build responseHandler:^(NSError * _Nullable error, IMSResponse * _Nullable response) {
     if (error) {
         //...
     } else {
         if (response.code == 200) {
             //...
         }
         else if (response.code == 401) {
             //处理认证错误
         }
         else {
             //...
         }
     }
    }];

    如果希望统一处理这种类型的认证错误,可通过以下步骤来实现。

    1. 继承IMSIoTAuthentication来实现自定义的身份认证功能。
      @interface XXCustomAuthentication : IMSIoTAuthentication
      @end
      @implementation XXCustomAuthentication
      
      - (void)handleRequestBeforeSend:(IMSRequest * _Nonnull)request
                              payload:(IMSRequestPayload * _Nonnull)payload
                           completion:(void (^ _Nonnull)(NSError * _Nullable error,
                                                         IMSResponse *_Nullable mockResponse,
                                                         IMSRequestPayload * _Nullable newPayload))completionHandler {
          [super handleRequestBeforeSend:request payload:payload completion:^(NSError * _Nullable error, IMSResponse * _Nullable mockResponse, IMSRequestPayload * _Nullable newPayload) {
              completionHandler(error, mockResponse, newPayload);
      
              if (mockResponse && mockResponse.code == 401) {
                  //自定义处理 401, 比如 toast
                  NSLog(@"before: 401");
              }
          }];
      }
      
      - (void)handleResponse:(IMSResponse * _Nonnull)response
                  completion:(void (^ _Nonnull)(NSError * _Nullable error, IMSResponse * _Nullable response))completionHandler {
          [super handleResponse:response
                     completion:^(NSError * _Nullable error, IMSResponse * _Nullable response) {
                         completionHandler(error, response);
      
                         if (response && response.code == 401) {
                             //自定义处理 401, 比如 toast
                             NSLog(@"after: 401");
                         }
                     }];
      }
      @end
    2. 注释身份认证的如下初始化代码。
      //[IMSCredentialManager initWithAccountProtocol:accountService.sessionProvider];
      //IMSIoTAuthentication *iotAuthDelegate = [[IMSIoTAuthentication alloc] initWithCredentialManager:IMSCredentialManager.sharedManager];
      //[IMSRequestClient registerDelegate:iotAuthDelegate forAuthenticationType:IMSAuthenticationTypeIoT];
    3. 修改成自定义的身份认证,即可完成统一的处理
      [IMSCredentialManager initWithAccountProtocol:accountService.sessionProvider];
      XXCustomAuthentication *iotAuthDelegate = [[XXCustomAuthentication alloc] initWithCredentialManager:IMSCredentialManager.sharedManager];
      [IMSRequestClient registerDelegate:iotAuthDelegate forAuthenticationType:IMSAuthenticationTypeIoT];
  • 获取用户身份凭证

    在账号登录成功后,可通过下面的方法同步获取用户身份凭证信息。

    #import <IMSAuthentication/IMSCredentialManager.h>
    
    IMSCredential *credential = [IMSCredentialManager sharedManager].credential;
    NSString *identityId = credential.identityId;
    NSString *iotToken = credential.iotToken;
  • 刷新用户身份凭证

    当同步方法获取到的用户身份凭证为空时,可以通过下面的方法强制异步刷新一个新的用户身份凭证信息。

    #import <IMSAuthentication/IMSCredentialManager.h>
    
    [[IMSCredentialManager sharedManager] asyncRefreshCredential:^(NSError * _Nullable error, IMSCredential * _Nullable credential) {
        if (error) {
            //刷新出错,参考错误码 IMSCredentialManagerErrorCode 处理
        } else {
            NSString *identityId = credential.identityId;
            NSString *iotToken = credential.iotToken;
        }
    }];