記錄多專案共用一個公眾號邏輯修改

weiweiyi發表於2023-02-21

前言

微信掃碼登陸,前段時間寫完微信掃碼登入後,由於有多個專案都需要微信登入,而公眾號的數量有限。 所以需要研究一下多個專案使用同一個公眾號登入。

思路

原來的思路: 每個後臺與微信伺服器之間進行通訊, 需要多個公眾號

那麼,使用一個公眾號的話,建立一箇中間伺服器,與微信進行通訊就行了。

同時,與微信伺服器互動的程式碼不需要在專案1、2中寫, 省下了很多程式碼編寫

image.png


先說一下前提: 本專案是先登入,然後繫結微信使用者後, 後續才能使用微信登入。

有了思路之後流程大概如下:

假如在登入的系統是: 專案1, 而伺服器收到微信推送事件後需要做這幾件事

  1. 判斷該事件是否是向 專案1 推送
  2. 校驗該微信使用者是否與 專案1 繫結
  3. 伺服器 向 專案1 傳送 登入成功的請求。
  4. 專案1 向登入成功的客戶端,執行登入成功邏輯
  5. 伺服器向微信公眾號, 傳送登入成功的資訊。

image.png

如何判斷事件是否屬於專案1

解決:專案1向伺服器傳送請求的時候帶上專案關鍵字

例如: 專案的名稱為 schedule, 則請求的時候帶上引數為shcedule

例如第5行, 引數帶上專案的關鍵字

1 final Map<String, String> variables = new HashMap<>();
2 variables.put("client", this.wxMpConfig.getClient());
3 variables.put("username", userDetails.getUsername());
4 variables.put("sessionId", sessionId);

5 String requestUrl = UserServiceImpl.addParam( this.wxMpConfig.getService() + "request/getBindQrCode", variables);

6 RestTemplate restTemplate = new RestTemplate();
7 String bindQrCode = restTemplate.getForObject(requestUrl, String.class, variables);

如何校驗該微信使用者是否與 專案1 繫結

方法1 :向專案1 傳送請求, 讓專案1來判斷。

方法2: 繫結使用者的時候,將微信使用者和使用者存到資料庫中,並記錄是哪一個專案

image.png

  • 方法1 需要 專案1 自己記錄使用者和微信使用者的對應關係,
  • 方法2 自己記錄了對應關係, 專案1 可選擇記錄或不記錄

伺服器 向 專案1 傳送 登入成功的請求。

需要我們根據專案關鍵字 client ,獲取 專案1的地址

這時候我們可以寫個前臺, 記錄該地址

image.png

final Map<String, String> variables = new HashMap<>();
variables.put("wsLoginToken", wsLoginToken);
variables.put("username", user.getUsername());

String url = setting.getUrl() + "/api/wechat/login";

CommonServiceImpl.httpPost(url, weChatUser, variables);

post請求用到的包是 org.springframework.web.client.RestTemplate

然後簡單封裝了一下, 並加入了請求重試

  @Retryable(value = {RestClientException.class, EOFException.class}, maxAttempts = 3,
          backoff = @Backoff(delay = 1000L,multiplier = 1))
  static public <T> void httpPost(String url , T entity, Map<String, String> variables) {

    //建立請求頭
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    // 新增url引數格式
    String requestUrl = CommonServiceImpl.addParam(url, variables);

    HttpEntity<T> requestEntity = new HttpEntity<T>(entity, headers);
    RestTemplate restTemplate = new RestTemplate();
    // 傳送post請求
    ResponseEntity<String> response = restTemplate.exchange(requestUrl, HttpMethod.POST, requestEntity, String.class, variables);

    // 判斷請求是否發生異常
    if(!response.getStatusCode().is2xxSuccessful()){
      System.out.println("請求失敗...");
      // 丟擲異常
      throw new RestClientException(response.getBody());
    }
  }

專案1 向登入成功的客戶端,執行登入成功邏輯


  @Override
  public void bindWsUuidToWeChatUser(String wsLoginToken, String username) {
    // 登入憑證 前臺憑該loginUid作為使用者名稱和密碼登入
    String loginUid = UUID.randomUUID().toString();
    this.map.put(loginUid, username);
    simpMessagingTemplate.convertAndSendToUser(wsLoginToken,
            "/stomp/scanLoginQrCode",
            loginUid);
  }

效果圖:

image.png

遇到的問題 unsafe url

文章連結

原始碼地址

https://github.com/weiweiyi18...

相關文章