記得看開發文檔
公眾平台后台修改接口權限:
網頁授權 | 網頁授權獲取用戶基本信息 | 無上限 | 已獲得 | 修改 |
修改:
.cn,開發版可以使ip,正式版要用域名
1、第一步:用戶同意授權,獲取code
一般由前段調用,拿到code,傳給后端。
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirec
參數 | 是否必須 | 說明 |
---|---|---|
appid | 是 | 公眾號的唯一標識 |
redirect_uri | 是 | 授權后重定向的回調鏈接地址, 請使用 urlEncode 對鏈接進行處理 |
response_type | 是 | 返回類型,請填寫code |
scope | 是 | 應用授權作用域,snsapi_base (不彈出授權頁面,直接跳轉,只能獲取用戶openid),snsapi_userinfo (彈出授權頁面,可通過openid拿到昵稱、性別、所在地。並且, 即使在未關注的情況下,只要用戶授權,也能獲取其信息 ) |
state | 否 | 重定向后會帶上state參數,開發者可以填寫a-zA-Z0-9的參數值,最多128字節 |
#wechat_redirect | 是 | 無論直接打開還是做頁面302重定向時候,必須帶此參數 |
用戶同意授權后
如果用戶同意授權,頁面將跳轉至 redirect_uri/?code=CODE&state=STATE。
code說明 : code作為換取access_token的票據,每次用戶授權帶上的code將不一樣,code只能使用一次,5分鍾未被使用自動過期。
2、通過code換取網頁授權access_token
獲取code后,請求以下鏈接獲取access_token: https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
參數 | 是否必須 | 說明 |
---|---|---|
appid | 是 | 公眾號的唯一標識 |
secret | 是 | 公眾號的appsecret |
code | 是 | 填寫第一步獲取的code參數 |
grant_type | 是 | 填寫為authorization_code |
3、第三步:刷新access_token(如果需要)
由於access_token擁有較短的有效期,當access_token超時后,可以使用refresh_token進行刷新,refresh_token有效期為30天,當refresh_token失效之后,需要用戶重新授權。
請求方法
獲取第二步的refresh_token后,請求以下鏈接獲取access_token:
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
參數 | 是否必須 | 說明 |
---|---|---|
appid | 是 | 公眾號的唯一標識 |
grant_type | 是 | 填寫為refresh_token |
refresh_token | 是 | 填寫通過access_token獲取到的refresh_token參數 |
4、第四步:拉取用戶信息(需scope為 snsapi_userinfo)
如果網頁授權作用域為snsapi_userinfo,則此時開發者可以通過access_token和openid拉取用戶信息了。
請求方法
http:GET(請使用https協議) https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
參數說明
參數 | 描述 |
---|---|
access_token | 網頁授權接口調用憑證,注意:此access_token與基礎支持的access_token不同 |
openid | 用戶的唯一標識 |
lang | 返回國家地區語言版本,zh_CN 簡體,zh_TW 繁體,en 英語 |
附:檢驗授權憑證(access_token)是否有效
請求方法
http:GET(請使用https協議) https://api.weixin.qq.com/sns/auth?access_token=ACCESS_TOKEN&openid=OPENID
參數說明
參數 | 描述 |
---|---|
access_token | 網頁授權接口調用憑證,注意:此access_token與基礎支持的access_token不同 |
openid | 用戶的唯一標識 |
我的代碼:
//wxLoginInfo 是后端自己測試時,傳url,可以直接請求,拿到code,重定向到callBackInfo
@RequestMapping("/wxLoginInfo")
@ResponseBody
public void wxLoginInfo(HttpServletRequest req,HttpServletResponse resp) throws IOException { String parameter = req.getParameter("url"); //String backUrl = AuthUtil.WEIXINURL+"xxxx/weixin/callBackInfo"; String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="+AuthUtil.APPID + "&redirect_uri="+URLEncoder.encode(parameter) + "&response_type=code" + "&scope=snsapi_userinfo"//彈出授權頁面,可通過openid拿到昵稱、性別、所在地。並且, 即使在未關注的情況下,只要用戶授權,也能獲取其信息 + "&state=STATE#wechat_redirect"; System.out.println("url=="+url); /* * https://open.weixin.qq.com/connect/oauth2/authorize? * appid=myAppid& * redirect_uri=https://xxxx.cn& * response_type=code& * scope=snsapi_userinfo& * state=STATE#wechat_redirect * * String url ="https://open.weixin.qq.com/connect/oauth2/authorize?appid="+AuthUtil.APPID + "&redirect_uri="+URLEncoder.encode(backUrl) + "&response_type=code" + "&scope=snsapi_base" + "&state=STATE#wechat_redirect";*/ resp.sendRedirect(url); }
//拿到code后請求接口,拿到用戶數據,關聯公眾平台后會拿到unionid,然后是進行的數據操作 @SuppressWarnings("unchecked") @RequestMapping("/callBackInfo") @ResponseBody public void callBackInfo(HttpServletRequest req,HttpServletResponse resp) throws IOException { BaseResponse<Object> result = new BaseResponse<Object>(StatusCode.Success); String code = req.getParameter("code"); String codeUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+AuthUtil.APPID + "&secret="+AuthUtil.APPSECRET + "&code="+code + "&grant_type=authorization_code"; JSONObject codeJson = AuthUtil.doGetJson(codeUrl); System.out.println("codeJson= "+codeJson); String openid = codeJson.getString("openid"); String unionid = "" ; Set<Object> keySet = codeJson.keySet(); for (Object object : keySet) { if(object.equals("unionid")){ unionid = codeJson.getString("unionid"); System.out.println("unionid==="+unionid); } } String accessToken = codeJson.getString("access_token"); String infoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token="+accessToken + "&openid="+openid + "&lang=zh_CN"; JSONObject info = AuthUtil.doGetJson(infoUrl); System.out.println("info= "+info); String nickname = info.getString("nickname"); String sex = info.getString("sex"); String city = info.getString("city"); String headimgurl = info.getString("headimgurl"); String openId = info.getString("openid"); System.out.println("openid= "+openId); System.out.println("sex= "+sex); System.out.println("city= "+city); System.out.println("nickname= "+nickname); System.out.println("headimgurl= "+headimgurl);
}
AuthUtil.APPID,AuthUtil.APPSECRET:公眾平台的appid和APPSECRET
package com.fltd.tourism.util; import java.io.IOException; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import net.sf.json.JSONObject; public class AuthUtil { public static final String WEIXINURL= "https://xxxxx.cn/"; public static JSONObject doGetJson(String url) throws ClientProtocolException, IOException{ JSONObject jsonObject = null; DefaultHttpClient client = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(url); HttpResponse response = client.execute(httpGet); HttpEntity entity = response.getEntity(); if(entity != null){ String result = EntityUtils.toString(entity,"UTF-8"); jsonObject = JSONObject.fromObject(result); } httpGet.releaseConnection(); return jsonObject; } }
總結:
1、其中 AuthUtil.APPID,AuthUtil.APPSECRET是微信公眾號正式的,不要弄錯了,很容易和小程序、開放平台、開發環境等弄混,回報錯。
2、wxLoginInfo中url,一定要看清楚是否和公眾號上的一致,不然也會報錯:redirect_url域名與后台配置不一致。
3、unionid正常情況是沒有的,要關聯上才會有。具體看微信的文檔