목표: 위챗 공식 계정으로 웹사이트에 로그인하고 사용자 정보 가져오기
사전 조건
- 위챗 공식 계정의 인증을 완료해야 합니다
- WeChat 서버의 콜백을 받을 수 있는 서버가 있어야 합니다
단계
1、위챗 공식 계정의 appid와 appsecret 가져오기
2、서버를 연동해 WeChat 서버의 콜백 받기. 도메인이 필요하고, 내부망 터널링 도구(예: cpolar)를 사용할 수 있습니다
먼저 그림에 표시된 항목을 준비해야 합니다
<img src="https://raw.githubusercontent.com/liyown/pic-go/master/blog/0" style="zoom:67%;" />설명:
URL은 WeChat 서버가 서비스 서버의 존재 여부를 검증하는 데 사용되므로, 요구사항에 맞춰 설정해야 합니다. 예를 들어 제 환경의 주소는 다음과 같습니다
JAVAhttps://13a34511.r1.cpolar.top/api/user/wxcheck따라서 자체 서비스에 응답용 엔드포인트를 준비해야 합니다
JAVA//外层还有/user @GetMapping("wxcheck") public String wxCheck(@RequestParam("signature") String signature, @RequestParam("timestamp") String timestamp, @RequestParam("nonce") String nonce, @RequestParam("echostr") String echostr) { if (userService.wxCheck(signature, timestamp, nonce, wxOpenConfig.getToken())) { return echostr; } else { return "error"; } }WeChat의 요구사항에 따라 데이터를 반환해야 하며, 다음과 같습니다:
1)token, timestamp, nonce 세 매개변수를 사전순으로 정렬합니다
2)세 매개변수의 문자열을 하나로 이어 붙인 뒤 sha1로 암호화합니다
3)개발자는 암호화된 문자열을 signature와 비교하여 해당 요청이 WeChat에서 왔음을 확인할 수 있습니다
JAVA@Override public Boolean wxCheck(String signature, String timestamp, String nonce, String token) { // 微信公众号接入校验 // 将token、timestamp、nonce三个参数进行字典序排序 String[] arr = new String[]{token, timestamp, nonce}; Arrays.sort(arr); // 将三个参数字符串拼接成一个字符串进行sha1加密 StringBuilder content = new StringBuilder(); for (String s : arr) { content.append(s); } String tmpStr = MYDigestUtils.sha1DigestAsHex(content.toString()); log.info("微信公众号接入校验,signature = {}, tmpStr = {}", signature, tmpStr); return signature.equals(tmpStr); }그런 다음 위 양식을 제출하면 검증 통과 안내가 표시됩니다
3、다음으로 access_token 가져오기
Render failed
요구사항에 따라 WeChat 리소스에 접근하는 token을 반환해야 합니다. WeChat의 리소스를 이용할 때는 이 token이 반드시 필요합니다. 예를 들어 뒤에서 생성할 QR 코드가 여기에 해당합니다
- 공식 문서개발 시작 / Access token 가져오기 (qq.com)
- 코드:
JAVA
@Override
public String getAccessToken() {
// 获取access_token
String url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",
wxOpenConfig.getAppId(), wxOpenConfig.getAppSecret());
// 发送请求
String result = restTemplate.getForObject(url, String.class);
log.info("获取access_token,result = {}", result);
return result;
}
4、Ticket이 포함된 QR 코드 생성
JAVA
@Override
public String getQRCode(String accessToken) {
// 获取二维码
String url = String.format("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=%s", accessToken);
// 5分钟过期
String body = WXUtils.getQRCodeBody("300", "QR_STR_SCENE");
String result = restTemplate.postForObject(url, body, String.class);
log.info("获取二维码,result = {}", result);
return result;
}
5、QR 코드의 ticket을 프런트엔드에 반환한 뒤, 프런트엔드에서 QR 코드 이미지를 요청해 사용자에게 표시합니다
6、사용자가 QR 코드를 스캔하면 이벤트 응답이 위 URL로 푸시됩니다. GET 요청이 POST 요청으로 변환될 뿐이며, 형식은 다음과 같습니다:
XML
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[subscribe]]></Event>
<EventKey><![CDATA[qrscene_123123]]></EventKey>
<Ticket><![CDATA[TICKET]]></Ticket>
</xml>
이벤트 유형은 물론 매우 많으므로, 유형별로 처리하도록 전략 패턴을 정의할 수 있습니다
CodeBlock Loading...
요청 수신 인터페이스는 다음과 같이 정의합니다
JAVA
@PostMapping("wxcheck")
public String event(@RequestBody String xml) {
String msgType = WXUtils.getMsgType(xml);
if ("event".equals(msgType)) {
DispatchEventHandle dispatchEventHandle = new DispatchEventHandle();
dispatchEventHandle.dispatch(JSONUtil.xmlToJson(xml));
}
return xml;
}