In WeChat development, there are often such needs: obtain user avatars, bind WeChat accounts to send messages to users... Then the prerequisite for achieving these is authorization!
1. Configure the secure callback domain name:
Before requesting user web page authorization by WeChat public account, developers need to go to the configuration option of "Development - Interface Permissions - Web Services - Web Accounts - Web Authorization to obtain user basic information" in the official website of the public platform to modify the authorization callback domain name. It is worth noting that this is to directly write the full domain name, such as: www.liliangel.cn. However, in our development of h5, we generally use secondary domain names, such as: h5.liliangel.cn, which is also in the secure callback domain names.
2. User-level authorization and silent authorization
1. The web page authorization initiated by snsapi_base is used to obtain the openid of the user entering the page, and is silently authorized and automatically jumped to the callback page. What the user perceives is that he directly enters the callback page.
2. Web page authorization initiated by snsapi_userinfo as scope is used to obtain basic user information. However, this authorization requires the user's manual consent, and since the user has agreed, it is not necessary to pay attention to it and the user's basic information can be obtained after authorization.
3. The difference between web authorization access_token and ordinary access_token
1. WeChat web page authorization is implemented through the OAuth2.0 mechanism. After the user authorizes the official account, the official account can obtain an interface call credential (web authorization access_token) unique to the web page authorization. The authorization interface call can be performed through the web page authorization access_token, such as obtaining user basic information;
2. For other WeChat interfaces, ordinary access_token calls are needed through the "Get access_token" interface in basic support.
4. Guide the user to the authorization page to agree to authorization and obtain the code
After WeChat is updated, the authorization page has also changed. Actually, I'm used to the classic green page...
js:
var center = { init: function(){ ....... }, enterWxAuthor: function(){ var wxUserInfo = localStorage.getItem("wxUserInfo"); if (!wxUserInfo) { var code = common.getUrlParameter('code'); if (code) { common.getWxUserInfo(); center.init(); }else{ //No WeChat user information, no authorization -->> Authorization is required, jump to the authorization page window.location.href = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='+ WX_APPID +'&redirect_uri='+ window.location.href +'&response_type=code&scope=snsapi_userinfo#wechat_redirect'; } }else{ center.init(); } }}$(document).ready(function() { center.enterWxAuthor();}Take scope=snsapi_userinfo as an example. When the page is loaded, enter the authorization method. First, get the wxUserInfo object from the cache. If there is any explanation, enter the initialization method directly. If not, determine whether the url contains a code. If there is a code, it means that it is the page after entering the authorization page callback. Then exchange the user information through the code. There is no code, that is, the user enters the page for the first time and guides to the authorization page. Redirect_uri is the current page address.
getWxUserInfo method:
/** * Get the basic information of the user after authorization*/ getWxUserInfo:function(par){ var code = common.getUrlParameter("code"); if (par) code = par; $.ajax({ async: false, data: {code:code}, type : "GET", url : WX_ROOT + "wechat/authorization", success : function(json) { if (json){ try { // Ensure that the wxUserInfo written is correct var data = JSON.parse(json); if (data.openid) { localStorage.setItem('wxUserInfo',json);//Write cache--WeChat user information} } catch (e) { // TODO: handle exception } } } } }); },5. Backend restful-- /wechat/authorization, exchange user information based on code
/** * WeChat authorization* @param code expires after use* * @return User basic information* @throws IOException */ @RequestMapping(value = "/authorization", method = RequestMethod.GET) public void authorizationWeixin( @RequestParam String code, HttpServletRequest request, HttpServletResponse response) throws IOException{ request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); LOGGER.info("RestFul of authorization parameters code:{}",code); try { String rs = wechatService.getOauthAccessToken(code); out.write(rs); LOGGER.info("RestFul of authorization is successful.",rs); } catch (Exception e) { LOGGER.error("RestFul of authorization is error.",e); } finally{ out.close(); } }There is an authorized access_token here. Remember: authorized access_token is not global access_token, and it requires the use of cache. I use redis here. I won’t say much about the specific configuration and write a related configuration blog post later. Of course, you can also use ehcache. There is a detailed introduction to the ehcahe configuration in my first blog.
/** * Get authorized tokens based on code are only available when authorizing, different from global access_tokens* @param code * @return * @throws IOException * @throws ClientProtocolException */ public String getOauthAccessToken(String code) throws ClientProtocolException, IOException{ String data = redisService.get("WEIXIN_SQ_ACCESS_TOKEN"); String rs_access_token = null; String rs_openid = null; String url = WX_OAUTH_ACCESS_TOKEN_URL + "?appid="+WX_APPID+"&secret="+WX_APPSECRET+"&code="+code+"&grant_type=authorization_code"; if (StringUtils.isEmpty(data)) { synchronized (this) { //Expired, String hs = apiService.doGet(url); JSONObject json = JSONObject.parseObject(hs); String refresh_token = json.getString("refresh_token"); String refresh_url = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid="+WX_APPID+"&grant_type=refresh_token&refresh_token="+refresh_token; String r_hs = apiService.doGet(refresh_url); JSONObject r_json = JSONObject.parseObject(r_hs); String r_access_token = r_json.getString("access_token"); String r_expires_in = r_json.getString("expires_in"); rs_openid = r_json.getString("openid"); rs_access_token = r_access_token; redisService.set("WEIXIN_SQ_ACCESS_TOKEN", r_access_token, Integer.parseInt(r_expires_in) - 3600); LOGGER.info("Set sq access_token to redis is successful.parameters time:{},realtime",Integer.parseInt(r_expires_in), Integer.parseInt(r_expires_in) - 3600); } }else{ //Not expired String hs = apiService.doGet(url); JSONObject json = JSONObject.parseObject(hs); rs_access_token = json.getString("access_token"); rs_openid = json.getString("openid"); LOGGER.info("Get sq access_token from redis is successful.rs_access_token:{},rs_openid:{}",rs_access_token,rs_openid); } return getOauthUserInfo(rs_access_token,rs_openid); } /** * Get user information based on authorized token* @param access_token * @param openid * @return */ public String getOauthUserInfo(String access_token,String openid){ String url = "https://api.weixin.qq.com/sns/userinfo?access_token="+ access_token +"&openid="+ openid +"&lang=zh_CN"; try { String hs = apiService.doGet(url); //Save user information saveWeixinUser(hs); return hs; } catch (IOException e) { LOGGER.error("RestFul of authorization is error.",e); } return null; }I was in a hurry and the code naming was messy. As you can see, I used a synchronization method to get the key from the cache as WEIXIN_SQ_ACCESS_TOKEN. If the instructions are retrieved, I will directly call the interface provided by WeChat through httpclient and return the string of user information to the front end. If it is not retrieved, it means that it is not or has expired. Then refresh the access_token according to refresh_token and write the cache. Since access_token has a short validity period, I set the cache expiration time here to reduce the time given by WeChat by another hour. Looking back at the code, I found that the above logic is a little problem. Writing like this will cause the first acquisition or cache failure to refresh the access_token for the first acquisition, which will not affect the use for the time being. I will make optimization and modify the TODO later.
6: Save user information
Usually, after authorization, we will save the user information to the database table, openid as the only primary key, and the foreign key will associate our own user table. In this way, no matter what business we want to carry out in the future or do operational data statistics, we have an association with the WeChat public account. It is worth noting that the headimgurl we obtained is a url address provided by WeChat. When the user modifys the avatar, the original address may be invalid, so it is best to save the image to the local server and then save the local address url!
The value returned by WeChat:
Reference link:
Official document of WeChat public platform: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842&token=&lang=zh_CN
Online interface debugging tool: http://mp.weixin.qq.com/debug
No official account benefits: test account application http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
The above is all the content of this article. I hope that the content of this article will be of some help to everyone’s study or work. I also hope to support Wulin.com more!