爲什麼需要微信授權?
進行微信授權之後可以獲得用戶的openid等信息,以便於執行接下來的支付等業務邏輯。
那麼在springboot項目中應該如何實現微信授權呢?
前期準備
首先需要在微信公衆平臺獲取測試號,測試號有兩個重要的信息,appID和appsecret,這個稍後在授權中需要用到。
然後查閱微信開發文檔,得知授權有如下的步驟
開發文檔:
https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html
一、用戶同意授權,獲取code
開發文檔中提到,獲取code需要引導用戶打開如下鏈接
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
裏面參數需要替換成自己的信息,需要注意的參數是REDIRECT_URL,這個REDIRECT_URL對應的是需要授權之後需要回調到自己後端的接口。
由於微信規定這個域名必須是已備案的域名,如果沒有域名可以在natapp做內網穿透,申請一個二級域名來進行測試。
申請完域名之後在測試號功能服務處進行修改,將授權回調域名修改成自己的
訪問上述鏈接之後,瀏覽器會重定向至回調接口,並攜帶code參數
二、通過code換取tokenAccess
第二步是通過code換取access_token,同時得到openid
下面進行編程測試
@RestController
@Slf4j
@RequestMapping("/weixin")
public class WeixinController {
@GetMapping("/auth")
public void auth(@RequestParam("code") String code){
log.info("進入auth方法");
log.info("code={}",code);
String url="https://api.weixin.qq.com/sns/oauth2/access_token?appid=YOUR_APPID&secret=YOUR_APPSECRET&code="+code+"&grant_type=authorization_code";
RestTemplate restTemplate=new RestTemplate();
String response=restTemplate.getForObject(url,String.class);
log.info("response={}",response);
}
}
然後在手機微信端打開鏈接:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx7ec1630ac1ea0cb7&redirect_uri=http://zhmb.natapp1.cc/sell/weixin/auth&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect
打開鏈接後會進入到後端接口,在後臺可以看到輸出的信息
2020-02-23 22:00:04.865 INFO 1444 --- [nio-8889-exec-3] c.pers.food.controller.WeixinController : 進入auth方法
2020-02-23 22:00:04.865 INFO 1444 --- [nio-8889-exec-3] c.pers.food.controller.WeixinController : code=06170Mec1K3Ipz0Id9fc1dsKec170MeA
2020-02-23 22:00:05.488 INFO 1444 --- [nio-8889-exec-3] c.pers.food.controller.WeixinController : response={"access_token":"30_3a4lrlE4Sg6BZ4x0kpbsCysrJTgo1cnlxoUX7yeZmLX-S3OBUXadcwPVBeR6v5A09VRlWK5Eu34rVo8HIBsUTiFhXduZ8XReBs6TD6YY1nI","expires_in":7200,"refresh_token":"30_jgKZkBLBRcQfop0XO-IF9KOw38qCpAlhvqH_C5h_BUFbGg_3F-zw_grw0rmzPthecKwHxmrf5f6ytbCpdhAxe8wUkvV_E4xnyrIfR7QTdDY","openid":"o4N1_wbiO2jaK2BqrBuGGZNH-8_I","scope":"snsapi_base"}
可見通過code換取到了access_token和openid,授權成功
使用第三方SDK,可以更方便實現微信授權,這裏使用的是WxJava實現微信授權
maven引入依賴
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>2.7.0</version>
</dependency>
配置javaconfig,目的是設置appId,和openSecret信息
yml:
wechat:
openAppId: yourAppId
openAppSecret: yourAppSecret
@Data
@Component
@ConfigurationProperties(prefix = "wechat")
public class WechatAccountConfig {
private String openAppId;
private String openAppSecret;
}
@Configuration
public class WechatMpConfig {
@Autowired
private WechatAccountConfig wechatAccountConfig;
@Bean
public WxMpService wxMpService(){
WxMpService wxMpService=new WxMpServiceImpl();
wxMpService.setWxMpConfigStorage(wxMpConfigStorage());
return wxMpService;
}
@Bean
public WxMpConfigStorage wxMpConfigStorage(){
WxMpInMemoryConfigStorage wxMpInMemoryConfigStorage=new WxMpInMemoryConfigStorage();
wxMpInMemoryConfigStorage.setAppId(wechatAccountConfig.getOpenAppId());
wxMpInMemoryConfigStorage.setSecret(wechatAccountConfig.getOpenAppSecret());
return wxMpInMemoryConfigStorage;
}
}
編寫controller
@Controller
@RequestMapping("/wechat")
@Slf4j
public class WechatController {
@Autowired
private WxMpService wxMpService;
//獲得code,這個returnurl是前端的地址
@GetMapping("/authorize")
public String authorize(@RequestParam("returnUrl") String returnurl){
String url="http://zhmb.natapp1.cc/sell/wechat/userInfo";
//這個方法的參數設置了鏈接中的回調url,scope,和state,返回的是微信的授權鏈接
String redirectUrl=wxMpService.oauth2buildAuthorizationUrl(url,WxConsts.OAUTH2_SCOPE_BASE, URLEncoder.encode(returnurl));
return "redirect:"+redirectUrl;
}
//重定向到授權鏈接之後會繼續執行下面的方法
@GetMapping("/userInfo")
public String userinfo(@RequestParam("code") String code,@RequestParam("state") String returnUrl){
WxMpOAuth2AccessToken wxMpOAuth2AccessToken=new WxMpOAuth2AccessToken();
try {
//用code換取accessToken
wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code);
} catch (WxErrorException e) {
log.error("微信網頁授權{}",e);
throw new OrderException(ResultEnum.WECHAT_MP_ERROR);
}
String openid=wxMpOAuth2AccessToken.getOpenId();
//returnUrl爲前端地址,最後給前端傳遞了用戶的openid
return "redirect:"+returnUrl+"?openid="+openid;
}
}
測試:
打開手機微信,訪問前端頁面,前端頁面會進入後端微信授權的接口,並傳遞自己的url,進行授權
下面爲執行oauth2buildAuthorizationUrl後返回的redirctUrl,可見即爲微信授權的鏈接
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx7ec1630ac1ea0cb7&redirect_uri=http%3A%2F%2Fzhmb.natapp1.cc%2Fsell%2Fwechat%2FuserInfo&response_type=code&scope=snsapi_base&state=http%3A%2F%2Fsell.com%2F%23%2F#wechat_redirect
下面爲執行oauth2getAccessToken後返回的對象,可見得到了accessToken和openId
WxMpOAuth2AccessToken{accessToken=‘30_uoDKwSy_QNKp1cA2m1G9GHEU5gwBnUfHeLc9ObtGIb7e5s5J51LAlUJS8l_f4PwUlolMo2W-2rERXQHrqMJNkiJFGjRGgnEMzsNLYVdI-ok’, expiresTime=7200, refreshToken=‘30_j6Y2MaPSbWIvhUR6oiOWOx0_EB8xhW2-cSVv7LUbMogwrVCTdEv_VFWm_3osGTqCE9OKCO_414sAIgQEO_YwnmEcMd5lluAPPkBFapQ4KfU’, openId=‘o4N1_wR0q47LWmxWq5JVa2vcs28A’, scope=‘snsapi_base’, unionId=‘null’}
完成以上授權操作之後會訪問前端頁面,並傳遞一個openid給前端,以便實現以後的業務邏輯