日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
微信小程序登錄與SpringSecurity結(jié)合的思路

 1. 前言

我們提供的服務(wù)有:成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、微信公眾號(hào)開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、施秉ssl等。為上千余家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的施秉網(wǎng)站制作公司

原本打算把Spring Security中OAuth2.0的機(jī)制講完后,用小程序登錄來實(shí)戰(zhàn)一下,發(fā)現(xiàn)小程序登錄流程和Spring Security中OAuth 2.0登錄的流程有點(diǎn)不一樣,就把寫了半天的東西全部推翻了。但是,但是過了一天之后,突然感覺又可以了。我們來一起試一試。

2. 小程序登錄流程分析

小程序的登錄流程是這樣的:

微信小程序登錄時(shí)序圖

而在Spring Security中的OAuth 2.0 Code模式是這樣的:

Spring Security OAuth2.0 Code模式時(shí)序圖

從這兩張圖上看最大的差別就是微信小程序中獲取code不需要通過后端服務(wù)器的調(diào)用,而Spring Security中需要(第1步,第2步,第3步)。騰訊應(yīng)該也是借鑒了OAuth 2.0,但是做了一些改動(dòng)。

讓我放棄的也是這個(gè)差別,有沒有人能想到解決方法呢?

假如說小程序已經(jīng)持有了code,它依然需要將code傳遞給后端服務(wù)器來執(zhí)行后面的流程。那么我們能不能利用圖2中第3個(gè)調(diào)用redirectUri的步驟呢?換個(gè)角度來看問題第三方就是小程序反正它也是將一個(gè)code傳遞給了后端服務(wù)器,只要返回登錄狀態(tài)就行了,反正剩下的登錄流程都跟小程序無關(guān)。我覺得它是可以的。在Spring Security中我們可以使用code通過tokenUri來換取token。那么在微信小程序登錄流程中,code最終換取的只是登錄態(tài),沒有特定的要求。但是后端肯定需要去獲取用戶的一些信息,比如openId,用戶微信信息之類的??傊鶕?jù)微信平臺(tái)提供的API來實(shí)現(xiàn)。通過改造tokenUri和userInfoUri可以做到這一點(diǎn)。

3. 思路借鑒

所有的猜想都沒有錯(cuò),而且我也實(shí)現(xiàn)了,但是改造成本過高了,寫了很多兼容性的代碼,如果不深入Spring Security,很難實(shí)現(xiàn)這一點(diǎn),而且也不好理解。

為了簡化實(shí)現(xiàn),我決定借鑒Spring Security中OAuth 2.0的思路。Filter攔截小程序登錄URL,然后通過RestTemplate執(zhí)行向微信服務(wù)器請(qǐng)求獲取結(jié)果,處理后返回登錄態(tài)。時(shí)序圖如下:

小程序登錄開發(fā)時(shí)序圖

對(duì)應(yīng)的偽代碼實(shí)現(xiàn):

 
 
 
 
  1. package cn.felord.spring.security.filter; 
  2.  
  3. import org.springframework.http.ResponseEntity; 
  4. import org.springframework.security.web.util.matcher.AntPathRequestMatcher; 
  5. import org.springframework.security.web.util.matcher.RequestMatcher; 
  6. import org.springframework.util.Assert; 
  7. import org.springframework.util.LinkedMultiValueMap; 
  8. import org.springframework.util.MultiValueMap; 
  9. import org.springframework.web.client.RestTemplate; 
  10. import org.springframework.web.filter.OncePerRequestFilter; 
  11. import org.springframework.web.util.UriComponentsBuilder; 
  12.  
  13. import javax.servlet.FilterChain; 
  14. import javax.servlet.ServletException; 
  15. import javax.servlet.http.HttpServletRequest; 
  16. import javax.servlet.http.HttpServletResponse; 
  17. import java.io.IOException; 
  18. import java.net.URI; 
  19.  
  20. /** 
  21.  * 小程序登錄過濾器 
  22.  * 
  23.  * @author felord.cn 
  24.  * @since 1.0.4.RELEASE 
  25.  */ 
  26. public class WeChatAppLoginFilter extends OncePerRequestFilter { 
  27.  
  28.     private final RequestMatcher requiresAuthenticationRequestMatcher; 
  29.     private final RestTemplate restTemplate; 
  30.     private String appId; 
  31.     private String secret; 
  32.     private static final String WX_URL = "https://api.weixin.qq.com/sns/jscode2session"; 
  33.  
  34.     public WeChatAppLoginFilter(String loginProcessingUrl, String appId, String secret) { 
  35.         this.appId = appId; 
  36.         this.secret = secret; 
  37.         Assert.notNull(loginProcessingUrl, "loginProcessingUrl must not be null"); 
  38.         this.requiresAuthenticationRequestMatcher = new AntPathRequestMatcher(loginProcessingUrl, "POST"); 
  39.         this.restTemplate = new RestTemplate(); 
  40.     } 
  41.  
  42.     @Override 
  43.     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { 
  44.  
  45.         // 攔截微信登錄 
  46.         if (requiresAuthenticationRequestMatcher.matches(request)) { 
  47.             //todo 從request中獲取 code 參數(shù) 這里邏輯根據(jù)你的情況自行實(shí)現(xiàn) 
  48.             String jsCode = "你自行實(shí)現(xiàn)從request中獲取"; 
  49.             //todo 必要的校驗(yàn)自己寫 
  50.             MultiValueMap queryParams = new LinkedMultiValueMap<>(); 
  51.             queryParams.add("appid", this.appId); 
  52.             queryParams.add("secret", this.secret); 
  53.             queryParams.add("js_code", jsCode); 
  54.             queryParams.add("grant_type", "authorization_code"); 
  55.  
  56.  
  57.             URI uri = UriComponentsBuilder.fromHttpUrl(WX_URL) 
  58.                     .queryParams(queryParams) 
  59.                     .build() 
  60.                     .toUri(); 
  61.             //todo 這里 Object 自行封裝為具體對(duì)象 
  62.             ResponseEntity result = this.restTemplate.getForEntity(uri, Object.class); 
  63.  
  64.             //todo 處理 result 比如后端存儲(chǔ)、后端授權(quán)、角色資源處理、注冊、對(duì)session_key的處理等等你需要的業(yè)務(wù)邏輯 
  65.             // 最后放入HttpServletResponse中返回前端返回 
  66.  
  67.         } else { 
  68.             filterChain.doFilter(request, response); 
  69.         } 
  70.     } 
  71. 最后一定別忘了把過濾器配置到WebSecurityConfigurerAdapter的HttpSecurity中去。

    4. 總結(jié)

    本篇講解了Spring Security和微信小程序登錄相結(jié)合的思路歷程。本來不需要長篇大論OAuth 2.0,之所以寫出來是讓你明白開發(fā)中要善于發(fā)現(xiàn)一些相似的東西,通過差異對(duì)比來探討他們結(jié)合的可能性,這也是一種自我提升的方法。方法遠(yuǎn)比結(jié)果重要,形成自己的方法論就能富有創(chuàng)造力。

     本文轉(zhuǎn)載自微信公眾號(hào)「碼農(nóng)小胖哥」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系碼農(nóng)小胖哥公眾號(hào)。


    當(dāng)前文章:微信小程序登錄與SpringSecurity結(jié)合的思路
    URL鏈接:http://m.5511xx.com/article/dpgeepd.html