記錄一下微信授權登錄的開發套路,免得過幾天又忘了
1. 先搞一下測試賬號
https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
2. 找到接口權限頁面
https://mp.weixin.qq.com/advanced/advanced?action=table&token=1523894466&lang=zh_CN
在頁面中找到這兒
點擊后面那個修改按鈕,配置好我們的回調的域名
然后進去看它的文檔
https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html
大概就以下幾步:
這一步需要get請求微信服務器的url地址:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
2 第二步:通過code換取網頁授權access_token
這一步需要get請求微信服務器地址:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
這一步需要get請求微信服務器地址:
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
4 第四步:拉取用戶信息(需scope為 snsapi_userinfo)
這一步需要get請求微信服務器地址:
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
這一步需要get請求微信服務器地址:
https://api.weixin.qq.com/sns/auth?access_token=ACCESS_TOKEN&openid=OPENID
下面上代碼:
application.properties
weixin.appID=wxbc35232a6eb75be1 weixin.appsecret=8294dc5fd2b123179a6e20a15a50c4cd # 微信登錄需要的四個請求url weixin.login_url=https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect weixin.back_url=http://arm5rq.natappfree.cc weixin.login.access_token_url=https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code weixin.snsapi_userinfo.url=https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN
讀取配置文件的配置類
@Data @Component public class WeiXinConfig { @Value("${weixin.appID}") private String appId; @Value("${weixin.appsecret}") private String appsecret; /** * 微信授權登錄 * 1: 用戶同意授權,獲取code 的請求url */ @Value("${weixin.login_url}") private String loginUrl; /** * 微信授權登錄回調用地址 */ @Value("${weixin.back_url}") private String loginCallBackUrl; @Value("${weixin.login.access_token_url}") private String loginAccessTokenUrl; @Value("${weixin.snsapi_userinfo.url}") private String userInfoUrl; }
WxLoginController.java
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.bangke.life.user.common.utils.NetUtil; import com.bangke.life.user.weixin.config.WeiXinConfig; import lombok.extern.slf4j.Slf4j; 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.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URLEncoder; @Slf4j @RequestMapping("/wx") @Controller public class WxLoginController { @Autowired private WeiXinConfig weiXinConfig; @GetMapping("/login") public void wxLogin(HttpServletRequest request, HttpServletResponse response) throws Exception { String callBack = URLEncoder.encode(weiXinConfig.getLoginCallBackUrl()+"/wx/callBack/","UTF-8"); String loginUrl = weiXinConfig.getLoginUrl(); loginUrl = String.format(loginUrl, weiXinConfig.getAppId(), callBack); log.info("loginUrl: {}", loginUrl); // 1. 重定向用戶授權頁面 response.sendRedirect(loginUrl); } /** * 2. 微信服務器重定向我們自定義的回調地址 * * @param request * @throws IOException */ @ModelAttribute("userInfo") @GetMapping("/callBack") public ModelAndView callBack(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String code = request.getParameter("code"); log.info("code: {} ", code); String loginAccessTokenUrl = weiXinConfig.getLoginAccessTokenUrl(); loginAccessTokenUrl = String.format(loginAccessTokenUrl, weiXinConfig.getAppId(), weiXinConfig.getAppsecret(), code); // 3. 請求獲取登錄access_token String result = NetUtil.get(loginAccessTokenUrl); JSONObject jsonObject = JSON.parseObject(result); // 從請求結果中獲取access_token 和 opendid String accessToken = jsonObject.getString("access_token"); String openid = jsonObject.getString("openid"); String userInfoUrl = weiXinConfig.getUserInfoUrl(); userInfoUrl = String.format(userInfoUrl, accessToken, openid); // 4. 拉取用戶信息 result = NetUtil.get(userInfoUrl); JSONObject userInfo = JSON.parseObject(result); log.info("userInfo : {} ", userInfo); ModelAndView mv = new ModelAndView(); mv.setViewName("login"); mv.addObject("userInfo", userInfo); return mv; } }
@Controller public class IndexController { @GetMapping("/") public String index() { return "index"; } }
再寫兩個html頁面
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scala=1.0"> <title>登錄</title> </head> <body style="font-size: 40px; text-align: center"> <a href="/wx/login">微信授權登錄</a> </body> </html>
login.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scala=1.0"> <title>個人信息</title> </head> <body style="font-size: 40px; text-align: center"> 用戶名:<span th:text="${userInfo.nickname}"></span> </body> </html>
好了, 就這么些代碼。
下面測試一下:
1. 請求: http://127.0.0.1
請求進入IndexController的index方法后,跳轉到index.html
2. 用戶同意
后台的邏輯是:
用戶同意登錄之后,用入WxLoginController#wxLogin方法-----> 微信服務器----> 重定向到WxLoginController#callBack方法 -----> 本地項目跳轉到login.html