
# 鉴权方式
当前纯前端的Demo，鉴权信息均在前端文件中，若后续需要在正式的环境中使用，请将相关鉴权信息转移到服务端。
1. 验证使用的鉴权信息。找到目录中的文件：src/api/config.js ： 
   ![](https://support.huaweicloud.com/devg-webdemo-cec/figure/zh-cn_image_0000001262696136.png)
   其中，appkey和appSecret为apifabric接口调用需要使用到的aksk，请联系运营人员获取。
   channelId为需要对接的渠道ID，具体值来源请以租户管理员登录AICC，点击进入"配置中心\>接入配置\>渠道配置"中，如下：
   图1渠道ID   
   ![](https://support.huaweicloud.com/devg-webdemo-cec/figure/zh-cn_image_0000001624148160.png)
   
   
2. 前端鉴权。代码的路径 src/api/webChat.js，具体代码参考如下： 
   ```
   /**
    * 申请api-fabric的token
    *
    * @returns {Promise<void>}
    */
   async applyToken() {
       if (this.appKey && this.appSecret) {
           let apiResult = await axios({
               url: '/apigovernance/api/oauth/tokenByAkSk',
               method: 'POST',
               headers: {
                   'Accept': 'application/json',
                   'Content-Type': 'application/json;charset=UTF-8'
               },
               data: {
                   app_key: this.appKey,
                   app_secret: this.appSecret
               }
           });
           if (apiResult.status !== 200) {
               return;
           }
           this.apiToken = apiResult.data['AccessToken'];
           if (this.userName) {
               await this.getMessageToken(true);
           }
           if (this.applyTask) {
               return;
           }
           //每10分钟刷新token
           this.applyTask = setInterval(()=>{
               this.applyToken()
           }, 10 * 60 * 1000);
    
       }
   }
   ```
   
   
3. 修改成后端鉴权。 
   1. 在正式使用的场合中，不建议将appkey和AppSecret直接写在前台代码中，可以通过请求服务端返回apifabric生成的token。 可以参考后台代码如下：该代码会返回appkey和apifabric生成的token。
      ```
      public class GetRequestTokenController {
       
          @Autowired
          RestTemplate restTemplate;
       
          @Value("${api.fabric.appKey}")
          String appKey;
       
          @Value("${api.fabric.appSecret}")
          String appSecret;
       
          @Value("${api.fabric.address}")
          String appAddress;
       
          @PostMapping("/getTokenAndAppKey")
          public JSONObject getTokenAndAppKey(){
              String token = getToken();
              JSONObject resp = new JSONObject();
              if(StringUtils.hasText(token)) {
                  resp.put("token",token);
                  resp.put("appKey",appKey);
              }
              return resp;
          }
       
          private String getToken(){
              JSONObject reqBody = new JSONObject();
              reqBody.put("app_key", appKey);
              reqBody.put("app_secret",appSecret);
              UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(appAddress);
              ResponseEntity<JSONObject> responseEntity =
                      restTemplate.exchange(
                              builder.build(true).toUri(),
                              HttpMethod.POST,
                              new HttpEntity<>(reqBody, null),
                              JSONObject.class);
              JSONObject response = responseEntity.getBody();
              if (response == null || response.isEmpty()) {
                  return "";
              }
              return response.getString("AccessToken");
          }
      }
      ```
      
   
   2. 该代码为Springboot框架中的controller，请在配置文件中添加以下配置：
      ```
      api.fabric:
        appKey: xxx
        appSecret: xxx
        appAddress: https://ip:port
      ```
      
   
   3. RestTemplate的生成请参考以下代码：
      ```
      import org.apache.http.conn.ssl.NoopHostnameVerifier;
      import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
      import org.apache.http.impl.client.CloseableHttpClient;
      import org.apache.http.impl.client.HttpClientBuilder;
      import org.apache.http.impl.client.HttpClients;
      import org.apache.http.ssl.SSLContexts;
      import org.apache.http.ssl.TrustStrategy;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
      import org.springframework.web.client.RestTemplate;
      import javax.net.ssl.SSLContext;
      /**
       * HttpConfig
       *
       * @author x30005416
       * @since 2021-11-22
       */
      @Configuration
      public class HttpConfig {
          /**
           * 可访问无证书https请求的restTemplate
           *
           * @return restTemplate
           * @throws Exception exception
           */
          @Bean
          public RestTemplate restTemplate() throws Exception {
              TrustStrategy acceptingTrustStrategy = (x509Certificates, authType) -> true;
              SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
              SSLConnectionSocketFactory connectionSocketFactory =
                      new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
              HttpClientBuilder httpClientBuilder = HttpClients.custom();
              httpClientBuilder.setSSLSocketFactory(connectionSocketFactory);
              CloseableHttpClient httpClient = httpClientBuilder.build();
              HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
              factory.setHttpClient(httpClient);
              factory.setConnectTimeout(20000);
              factory.setConnectTimeout(20000);
              return new RestTemplate(factory);
          }
      }
      ```
      
   
   4. 前台需要调用后台的服务，来获取Token和AppKey和apifabric的token，结合上述后台代码，前台可对 applyToken 方法进行改造。
      ```
      async applyToken () {
              let apiResult = await axios({
                  url: '/getTokenAndAppKey',
                  method: 'GET',
                  headers: {
                      'Accept': 'application/json',
                      'Content-Type': 'application/json;charset=UTF-8'
                  }
              });
              if (apiResult.status !== 200) {
                  return;
              }
              this.apiToken = apiResult.data['token'];
              this.appKey = apiResult.data['appKey'];
              if (this.userName) {
                  await this.getMessageToken();
              }
              if (this.applyTask) {
                  return;
              }
              //每55分钟刷新token
              this.applyTask = setInterval(this.applyToken, 55 * 60 * 1000);
      }
      ```
      
   
   
   
   
 
