章節小結:
1.學會了微信授權的步驟,學會了微信授權的文檔
2.學會了使用natapp內網穿透工具
3.加深了虛擬機的網絡配置以及基本使用
4.學會了抓包購票工具fiddler的使用
5.微信授權步驟
分析微信登錄跳轉的幾個路徑
1)sell.com 這是我本地在電腦端口微信界面點擊的時候的的入口,這里是可以調到我的本地的虛擬機中的項目192.168.1.105中去
2)sell.com /sell/buyer/product/list獲取商品list。這是在nginx中配置的。Nginx中/sell/這個路徑設置之后尋找192.168.1.102:8080,這就是我的本地項目的路徑,sell.com /sell/buyer/product/list
3)http://192.168.1.102:8080/sell/wechat/authorize?returnUrl=http%3A%2F%2Fsell.com%2F%23%2F 這個是我在虛擬機項目中設置的尋找openid的路徑http://192.168.1.102:8080/sell/wechat/authorize參數是虛擬機項目自己上,這是本地項目中查找openid的第一步找到code
4)http://xys.natapp1.cc/sell/wechat/userInfo?code=011XT9ko0SA33l1TbWjo00O6ko0XT9kq&state=http%3A%2F%2Fsell.com%2F%23%2F 這是我本地項目中查找openid的第二步,找出openid
5)http://sell.com/sell/buyer/product/list,再查一次商品
微信授權獲取openid:
根據微信給的接口說明,這是文檔:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_3我們可以分為以下幾步:
設置域名:
1.在natapp上面買一個域名,我的是http://xys.natapp1.cc
2.本地設置服務器穿透,開啟natapp.exe,開啟命令:natapp -authtoken=e922eb840cb4b7df
3.微信公眾號我這邊弄得是接口測試號
4.外網訪問驗證
手動獲取獲取用戶OpenID:
OpenId是一個用戶的唯一標示,通過微信提供的接口我們可以獲取這個唯一標示
上面圖中第一步:設置域名已經完成,接下來就是第二步獲取OpenID,細分為幾步
1.用戶同意授權,獲得code
這是微信提供的模仿路徑
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
然后進行修改
設置權限
appid=wxdf2b09f280e6e6e2
redirect_uri=http://xys.natapp1.cc/sell/weixin/auth
scope=snsapi_base
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxdf2b09f280e6e6e2&redirect_uri=http://xys.natapp1.cc/sell/weixin/auth&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect 當該路徑成功之后,微信方面就會跳轉成這樣 http://xys.natapp1.cc/sell/weixin/auth?code=adfsdfsdfs&state=STATE
補充上方法路徑:sell/weixin/auth所以我們可以獲取code,而這個state想寫就寫不寫算噠,這是給我們自定義的參數
@RestController @RequestMapping("/weixin") @Slf4j public class WinxinController { @GetMapping("/auth") public void auth(@RequestParam("code") String code) { log.info("進入auth方法。。。"); log.info("code={}", code); } }
已獲得code
2.通過code換取網頁授權access_token
微信提供的模仿接口
appid=wxdf2b09f280e6e6e2
secret=f924b2e9f140ac98f9cb5317a8951c71
https://api.weixin.qq.com/sns/oauth2/access_token?appid=wxdf2b09f280e6e6e2&secret=f924b2e9f140ac98f9cb5317a8951c71&code=CODE&grant_type=authorization_code
然后我們在auth方法中請求這個鏈接獲取回調參數
下圖是我們auto定義的返回的參數
3.拉取用戶信息(需scope為 snsapi_userinfo)
與scope=snsapi_base不同的是,用戶需要授權而不是直接進入
appid=wxdf2b09f280e6e6e2
redirect_uri=http://xys.natapp1.cc/sell/weixin/auth
scope=snsapi_base
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxdf2b09f280e6e6e2&redirect_uri=http://xys.natapp1.cc/sell/weixin/auth&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
獲取的參數更多一些
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
SDK獲取OpenID(這才是項目中使用的):
Github:https://github.com/Wechat-Group/WxJava,里面也有寫好的怎么使用的文檔
這里我們使用了別人寫好的SDK工具,我們直接拿來就可以用,導入maven
<dependency> <groupId>com.github.binarywang</groupId> <artifactId>weixin-java-mp</artifactId> <version>3.3.0</version> </dependency>
Github:Wechat-Group/WxJava文檔
API文檔
獲取openid 重定向到 /sell/wechat/authorize 參數 returnUrl: http://xxx.com/abc //【必填】 返回 http://xxx.com/abc?openid=oZxSYw5ldcxv6H0EU67GgSXOUrVg
此時我們創建一個WechatAccountConfig放在config下,這是全文配置,獲取配置文件信息@Component@ConfigurationProperties(prefix = "wechat")
package com.xiong.sell.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Data @Component @ConfigurationProperties(prefix = "wechat") public class WechatAccountConfig { private String mpAppId; private String mpAppSecret; }
配置文件中
wechat:
mpAppId: wxdf2b09f280e6e6e2
mpAppSecret: f924b2e9f140ac98f9cb5317a8951c71
然后配置WechatMpConfig配置文件中
package com.xiong.sell.config; import me.chanjar.weixin.mp.api.WxMpConfigStorage; import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; @Component public class WechatMpConfig { @Autowired private WechatAccountConfig accountConfig; @Bean public WxMpService wxMpService() { WxMpService wxMpService = new WxMpServiceImpl(); wxMpService.setWxMpConfigStorage(wxMpConfigStorage()); return wxMpService; } @Bean public WxMpConfigStorage wxMpConfigStorage() { WxMpInMemoryConfigStorage wxMpConfigStorage = new WxMpInMemoryConfigStorage(); wxMpConfigStorage.setAppId(accountConfig.getMpAppId()); wxMpConfigStorage.setSecret(accountConfig.getMpAppSecret()); return wxMpConfigStorage; } }
@Bean告訴項目,我這里是一個bean
@Component告訴項目我這里是一個組件,可以掃描我
@Autowired
private WechatAccountConfig accountConfig;
這個時候就會調用相同返回參數的配置bean
創建WechatController類,生成aothorize方法
package com.xiong.sell.controller; import com.xiong.sell.enums.ResultEnum; import com.xiong.sell.exception.SellException; import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.net.URLEncoder; /** * @author Xiong YuSong * 2019/1/24 11:41 */ @Controller @RequestMapping("wechat") @Slf4j public class WechatController { @Autowired private WxMpService wxMpService; /** * 獲取code * @param returnUrl * @return */ @GetMapping("/authorize") public String authorize(@RequestParam("returnUrl") String returnUrl) { //1. 配置 //2. 調用方法 String url = "http://xys.natapp1.cc/sell/wechat/userInfo"; String redirectUrl = wxMpService.oauth2buildAuthorizationUrl(url, WxConsts.OAuth2Scope.SNSAPI_USERINFO, URLEncoder.encode(returnUrl)); return "redirect:" + redirectUrl; } /** * 通過code獲得user信息,然后再回調 * @param code * @param returnUrl * @return */ @GetMapping("/userInfo") public String userInfo(@RequestParam("code") String code, @RequestParam("state") String returnUrl) { WxMpOAuth2AccessToken wxMpOAuth2AccessToken = new WxMpOAuth2AccessToken(); try { wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code); } catch (WxErrorException e) { log.error("【微信網頁授權】{}", e); throw new SellException(ResultEnum.WECHAT_MP_ERROR.getCode(), e.getError().getErrorMsg()); } String openId = wxMpOAuth2AccessToken.getOpenId(); return "redirect:" + returnUrl + "?openid=" + openId; } }
成功返回一個url:"redirect:" + returnUrl + "?openid=" + openId;
前端驗證:
補充一個買家信息,和圖片路徑顯示
如果無法加載則:Ctrl+F9進行靜態文件加載,頁面刷新Ctrl+Shift+R
前端項目配置獲取后端項目路徑以及openid獲取路徑
路徑以及修改地方
重新部署
將重新打包好的項目放到網站的根目錄下去
抓包工具fiddler
通過抓包工具我們可以看出,虛擬機項目中尋找微信身份驗證的路徑是錯誤的
找了半天是路徑打錯了
最后我把虛擬機中項目中查找openid的路徑直接寫為我的本機Ip+端口地址,然后成功了,這說明內網穿透並沒有什么用