微信三方登入
準備工作
微信授權登錄讓微信用戶使用微信身份安全登錄第三方應用或網站,在微信用戶授權登錄已接入微信OAuth2.0的第三方應用后,第三方可以獲取到用戶的接口調用憑證(access_token),通過access_token可以進行微信開放平臺授權關系接口調用,從而可實現獲取微信用戶基本開放信息和幫助用戶實現基礎開放功能等。
微信OAuth2.0授權登錄目前支持authorization_code模式,適用于擁有server端的應用授權。該模式整體流程為:
??? 第三方發起微信授權登錄請求,微信用戶允許授權第三方應用后,微信會拉起應用或重定向到第三方網站,并且帶上授權臨時票據code參數;
??? 通過code參數加上AppID和AppSecret等,通過API換取access_token;
??? 通過access_token進行接口調用,獲取用戶基本數據資源或幫助用戶實現基本操作。
??? 在這里插入圖片描述
??? 第一步:請求CODE
第三方使用網站應用授權登錄前請注意已獲取相應網頁授權作用域(scope=snsapi_login),則可以通過在PC端打開以下鏈接:
https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
若提示“該鏈接無法訪問”,請檢查參數是否填寫錯誤,如redirect_uri的域名與審核時填寫的授權域名不一致或scope不為snsapi_login。
參數說明
參數 是否必須 說明
appid 是 應用唯一標識
redirect_uri 是 請使用urlEncode對鏈接進行處理
response_type 是 填code
scope 是 應用授權作用域,擁有多個作用域用逗號(,)分隔,網頁應用目前僅填寫snsapi_login即
state 否 用于保持請求和回調的狀態,授權請求后原樣帶回給第三方。該參數可用于防止csrf攻擊(跨站請求偽造攻擊),建議第三方帶上該參數,可設置為簡單的隨機數加session進行校驗
返回說明
用戶允許授權后,將會重定向到redirect_uri的網址上,并且帶上code和state參數
redirect_uri?code=CODE&state=STATE
若用戶禁止授權,則重定向后不會帶上code參數,僅會帶上state參數
redirect_uri?state=STATE
代碼如下:
@RequestMapping(value = "/wxLoginPage")
??? public String wxKfLoginPage(HttpServletRequest request) throws Exception {
??????? // 防止csrf攻擊(跨站請求偽造攻擊)
??????? String state = UUID.randomUUID().toString().replaceAll("-", "");
??????? HttpSession session = request.getSession();
??????? //存入session
??????? session.setAttribute("wechat-kf-state",state);
??????? //普通微信三方地址
??????? String url = "https://open.weixin.qq.com/connect/qrconnect?" +
??????????????? "appid="+constants.getWeCatKfAppId() +
??????????????? "&redirect_uri="+constants.getWeCatKfRedirectUrl()+
??????????????? "&response_type=code" +
??????????????? "&scope=snsapi_login" +
??????????????? "&state="+state+
??????????????? "#wechat_redirect";
??????? return "redirect:"+url;
??? }
??
第二步:執行成功后會執行第一步的回調方法
?@RequestMapping("/callBack")
??? public String callBack(HttpServletRequest request){
??????? //得到code用于交換token
??????? String code = request.getParameter("code");
??????? String state = request.getParameter("state");
??????? //判斷state是否合法
??????? String stateStr = (String)request.getSession().getAttribute("wechat-kf-state");
??????? if(StringUtils.isEmpty(code)||StringUtils.isEmpty(state)||!state.equals(stateStr)){
??????????? request.setAttribute("msg","非法操作,請重新登錄!");
??????????? return "userInfo";
??????? }
??????? //用戶授權后的code換取token
??????? Map token = wechatService.getAccessToken(code,constants.getWeCatKfAppId(),constants.getWeCatKfAppSecret());
??????? //判斷是否成功獲取到了token
??????? if(token.get("errcode")!=null){
??????????? request.setAttribute("msg","token獲取失敗,請重新登錄");
??????????? return "userInfo";
??????? }
??????? if(StringUtils.isEmpty((String)token.get("access_token"))||StringUtils.isEmpty((String)token.get("openid"))){
??????????? request.setAttribute("msg","access_token拉取失敗,請重新登錄");
??????????? return "userInfo";
??????? }
??????? //刷新accesstoken
??????? Map refreshToken = wechatService.refrehToken(constants.getWeCatKfAppId(), (String) token.get("refresh_token"));
??????? //使用token交換獲取用戶信息
??????? WxchatUser user = wechatService.getUserInfo(refreshToken);
??????? //將用戶信息入棧
??????? request.setAttribute("user",user);
??????? return "userInfo";
??? }
???
第三步:在回調方法中的通過code換取accesstoken、
/**
???? * 通過code獲取token
???? * @return
???? */
??? public Map getAccessToken(String code,String appid,String secret){
??????? //構建請求數據
??????? String urlToken = "https://api.weixin.qq.com/sns/oauth2/access_token";
??????? Map t = new HashMap();
??????? t.put("appid",appid);
??????? t.put("secret",secret);
??????? t.put("code",code);
??????? t.put("grant_type","authorization_code");
??????? //調用httpclient處理請求得到返回json數據
??????? String returnJson = HttpClientUtil.doGet(urlToken, t);
??????? Map token = (Map) JSONObject.parse(returnJson);
??????? return token;
??? }
??
第四步:通過accesstoken和openid獲取用戶信息
/**
???? * 通過token獲取用戶信息
???? * @param token
???? * @return
???? */
??? public WxchatUser getUserInfo(Map token){
??????? String urlUser = "https://api.weixin.qq.com/sns/userinfo";
??????? //構建請求數據
??????? Map u = new HashMap();
??????? u.put("access_token",token.get("access_token"));
??????? u.put("openid",token.get("openid"));
??????? u.put("lang","zh_CN");
??????? //調用httpclient處理請求得到用戶信息json數據
??????? String user = HttpClientUtil.doGet(urlUser, u);
??????? //轉換成用戶對象
??????? WxchatUser wxchatUser = JSONObject.parseObject(user, WxchatUser.class);
??????? return wxchatUser;
??? }
第五步:刷新token(可省略這步)
?/**
???? * 刷新token處理
???? * @return
???? */
??? public Map refrehToken(String appid,String refresh_token){
??????? String urlRefresh = "https://api.weixin.qq.com/sns/oauth2/refresh_token";
??????? //構建請求參數
??????? Map m = new HashMap();
??????? m.put("appid",appid);
??????? m.put("grant_type","refresh_token");
??????? m.put("refresh_token",refresh_token);
??????? //調用httpclient發出請求
??????? Map refreshToken = (Map)JSONObject.parse(HttpClientUtil.doGet(urlRefresh, m));
??????? return refreshToken;
??? }
總結
- 上一篇: 【图】上海居住证办理指南
- 下一篇: 【转】国内人才《上海市居住证》续办需提供