WeChat の開発では、ユーザー アバターの取得、ユーザーにメッセージを送信するための WeChat ID のバインドなどのニーズがよくあります。これらを実現するための前提条件は承認です。
WeChat 公式アカウントがユーザーの Web ページ認証をリクエストする前に、開発者は、パブリック プラットフォームの公式 Web サイトの [基本的なユーザー情報を取得するための Web ページの認証] 設定オプションで、認証コールバック ドメイン名を www.liliangel のように直接記述していることに注意してください。 CN。ただし、h5 を開発する場合は、通常、安全なコールバック ドメイン名にも含まれる h5.liliangel.cn などの第 2 レベル ドメイン名を使用します。
2. ユーザーレベルの認証とサイレント認証
2. ユーザーの基本情報を取得するためにスコープが使用されるため、snsapi_userinfo で開始される Web ページの承認。しかし、このような認可にはユーザーの手動による同意が必要であり、ユーザーが同意しているため、認可後は特に意識することなくユーザーの基本情報を取得することができる。
3. Web ページの認証 access_token と通常の access_token の違い
2.基本サポートの「get access_token」インターフェイス。
4. 認証ページにアクセスして認証に同意し、コードを取得するようにユーザーを案内します
WeChat の更新後、認証ページも変更されました。実際、私は緑色のクラシックページに慣れています...
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{ //没有微信用户信息,没有授权-->> 需要授权,跳转授权页面 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(); }
ページが読み込まれたら、最初に認証メソッドを入力します。キャッシュから wxUserInfo オブジェクトを取得します。ある場合は、以前に許可されていることを意味し、直接初期化メソッドに入ります。そうでない場合は、URL にコードが含まれているかどうかを確認します。コードがある場合は、それが認証ページのコールバックに入った後のページであることを示し、コードをユーザー情報と交換できます。コードはありません。つまり、ユーザーが初めてページにアクセスすると、redirect_uri が現在のページ アドレスになります。
getWxUserInfoメソッド:
/** * 授权后获取用户的基本信息 */ 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 { //保证写入的wxUserInfo是正确的 var data = JSON.parse(json); if (data.openid) { localStorage.setItem('wxUserInfo',json);//写缓存--微信用户信息 } } catch (e) { // TODO: handle exception } } } }); },
5. バックエンドrestful--/wechat/authorization、コードに従ってユーザー情報を交換します
/** * 微信授权 * @param code 使用一次后失效 * * @return 用户基本信息 * @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(); } }
ここに承認がありますaccess_token 、覚えておいてください: access_token 非グローバル access_token を承認するには、キャッシュを使用する必要があります。ここでは、特定の構成については説明しません。もちろん、ehcache を使用することもできます。 ehcahe の構成については、最初のブログで詳しく紹介しています。
/** * 根据code 获取授权的token 仅限授权时使用,与全局的access_token不同 * @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) { //已过期,需要刷新 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{ //还没有过期 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); } /** * 根据授权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); //保存用户信息 saveWeixinUser(hs); return hs; } catch (IOException e) { LOGGER.error("RestFul of authorization is error.",e); } return null; }
急いでいたのでコードネームがめちゃくちゃでした。ご覧のとおり、同期メソッドを使用しました。まず、キャッシュからキー WEIXIN_SQ_ACCESS_TOKEN を取得し、それが期限切れになっていない場合は、httpclient 経由で WeChat が提供するインターフェイスを直接呼び出して、ユーザー情報の文字列を返します。フロントエンドへ。取得できない場合は、存在しないか期限切れになっているので、refresh_tokenに従ってaccess_tokenをリフレッシュし、キャッシュを書き込みます。安全のため、access_tokenの有効期限を設定します。ここで有効期限を入力し、WeChat によって指定された時間から 1 時間を差し引きます。コードを振り返ってみると、上記のロジックに少し問題があることがわかりました。このように書くと、初回またはキャッシュの有効期限が切れた後に access_token が更新されます。当面は使用に影響はありません。最適化と修正TODOは後ほど行います。
6: ユーザー情報を保存します
WeChat によって返される値:
WeChat 開発のための作成者 Web ページの承認に関するその他の関連記事については、PHP 中国語 Web サイトに注目してください。