During development, there is often a need to get a user's profile picture and bind a number to send a message to the user. so the prerequisite for achieving this is authorization! During development, there is often a need to get a user's profile picture and bind a number to send a message to the user. so the prerequisite for achieving this is authorization!
1. configure the security callback domain name:
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 user information, no authorization --> authorization 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 loading a page, you can access the authorization method. First, you can obtain the wxUserInfo object from the cache. if it indicates that you have already authorized it, you can directly access the initialization method. If no, determine whether the url contains code. if the code indicates that the authorization page is called back, you can exchange the code for user information. No code, that is, the user enters the page for the first time and directs to the authorization page. redirect_uri is the current page address.
GetWxUserInfo method:
/*** Obtain basic user information 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 written wxUserInfo is correct var data = JSON. parse (json); if (data. openid) {localStorage. setItem ('wxuserinfo', json); // write cache -- user information }}catch (e) {// TODO: handle exception }}}});},
5. the background restful --/wechat/authorization, exchange user information based on the code
/*** Authorization ** @ param code becomes invalid once it is used ** @ return basic user 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 ();}}
Here is an authorization access_token. remember: to authorize access_token to be a non-global access_token, you need to use the cache. here I am using redis. the specific configuration is not described later in the relevant configuration blog. of course, you can also use ehcache, the ehcahe configuration is described in detail in my first blog.
/*** The tokens authorized by code can only be used for authorization, different from the global access_token * @ param code * @ return * @ throws IOException * @ throws ClientProtocolException */public String getoauthaccesen en (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. you need to refresh 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 = token ("access_token"); String token = token ("expires_in"); rs_openid = r_json.getString ("openid"); 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 {// String hs = apiService not expired yet. 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 );} /*** obtain user information based on the 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 the user information saveWeixinUser (hs); return hs;} catch (IOException e) {LOGGER. error ("RestFul of authorization is error. ", e);} return null ;}
At that time, the code name was messy. As you can see, I used a synchronous method to first obtain the WEIXIN_SQ_ACCESS_TOKEN as the key from the cache. if the key has not expired, I directly call the provided interface through httpclient, returns the user information string to the front end. If the token is not obtained, it indicates that the token does not exist or has expired, refresh the access_token based on the refresh_token and then write the cache. because the access_token has a short validity period, in order to insure against this, I set the cache expiration time to reduce the time by another hour. Looking back at the code, we found that the above logic had a little problem. writing this will refresh the first time you get the access_token or the cache becomes invalid. this will not affect your use, optimize and modify TODO later.
6. save user information
Generally, after authorization, we save user information to the database table. openid is the unique primary key, and the foreign key is associated with our own user table, no matter what business is to be carried out in the future or conduct operation data statistics, there is a correlation with the public number. It is worth noting that the headimgurl we get is a provided url address. when the user modifies the Avatar, the original address may be invalid, therefore, it is best to save the image to the local server and then save the local address url!
Returned value:
For more development-related articles on Author web page authorization, please follow PHP Chinese network!