WeChat에서 개발한 작성자 웹페이지 인증

高洛峰
풀어 주다: 2017-02-15 11:15:21
원래의
2254명이 탐색했습니다.

WeChat 개발에는 종종 사용자 아바타 획득, WeChat ID 바인딩을 통해 사용자에게 메시지 보내기 등의 요구 사항이 있습니다. 그런 다음 이를 달성하기 위한 전제 조건은 승인입니다!

1. 보안 콜백 도메인 이름 구성:

微信开发之Author网页授权

WeChat 공식 계정이 사용자 웹을 요청하기 전 페이지 승인을 위해서는 개발자가 먼저 공개 플랫폼의 공식 웹사이트에서 "개발 - 인터페이스 권한 - 웹 서비스 - 웹 계정 - 기본 사용자 정보를 얻기 위한 웹 승인" 구성 옵션으로 이동하여 승인 콜백 도메인 이름을 수정해야 합니다. 전체 도메인 이름은 www.liliangel.cn과 같이 여기에 직접 기록되어 있습니다. 하지만 우리가 h5를 개발할 때 일반적으로 안전한 콜백 도메인 이름에도 포함되는 h5.liliangel.cn과 같은 2차 도메인 이름을 사용합니다.

2. 사용자 수준 인증 및 자동 인증

1. 범위에 따라 snsapi_base로 시작된 웹 페이지 인증이 사용됩니다. 페이지에 진입한 사용자의 openid는 자동으로 인증되어 자동으로 콜백 페이지로 이동합니다. 사용자가 인식하는 것은 콜백 페이지에 직접 들어간다는 것입니다.

2. snsapi_userinfo 범위로 시작되는 웹 페이지 인증은 사용자의 기본 정보를 얻는 데 사용됩니다. 그러나 이러한 승인을 위해서는 사용자가 수동으로 동의해야 하며, 사용자가 동의하였으므로 별도의 주의는 필요하지 않으며, 승인 후에는 사용자의 기본정보를 얻을 수 있습니다.

3. 웹페이지 인증 access_token과 일반 access_token의 차이점

1. WeChat 웹페이지 인증은 사용자가 인증한 후 구현됩니다. 공식 계정, 공용 계정은 웹 페이지 인증 access_token을 통해 웹 페이지 인증 access_token을 통해 기본 사용자 정보 획득 등의 인증 후 인터페이스 호출이 가능합니다. >

2. 다른 WeChat 인터페이스를 전달해야 합니다. 기본 지원의 "get access_token" 인터페이스는 일반 access_token 호출을 얻는 데 사용됩니다.

4. 사용자가 승인 페이지에 들어가 승인에 동의하고 코드를 받도록 안내합니다.

微信开发之Author网页授权

위챗 업데이트 이후 인증페이지도 변경되었습니다. 사실 저는 녹색클래식페이지가 익숙합니다..

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();
}
로그인 후 복사

scope=snsapi_userinfo를 예로 들면, 페이지가 로드되면 먼저 캐시에서 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. 위챗/인증, 코드에 따라 사용자 정보 교환


  /**
     * 微信授权
     * @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을 승인합니다. 여기서는 redis를 사용하고 있으며 나중에 관련 구성 블로그를 작성하겠습니다. 물론 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: 사용자 정보 저장

일반적으로 인증 후 사용자 정보를 데이터베이스 테이블에 저장합니다. openid는 유일한 기본 키이고 외래 키는 자체 사용자와 연결됩니다. 테이블이므로 앞으로 어떤 사업을 하든, 운영 데이터 통계를 하든 WeChat 공식 계정과 관계가 있습니다.

우리가 획득한 headimgurl은 WeChat에서 제공하는 URL 주소라는 점에 유의할 필요가 있습니다. 사용자가 아바타를 수정하면 원래 주소가 유효하지 않게 될 수 있으므로 이미지를 로컬 서버에 저장한 후 저장하는 것이 가장 좋습니다. 현지 주소 URL!

WeChat에서 반환된 값:

微信开发之Author网页授权

WeChat 개발을 위한 작성자 웹페이지 인증에 대한 더 많은 관련 기사를 보려면 PHP 중국어 웹사이트에 주목하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿