微信授权登录-手机端

1.页面链接发送请求

    <a href="http://192.168.1.87:8189/wx_login" style="color:#000;" >手机微信授权</a>

 

2.后台接受请求

/**
     * 手机_微信授权
     * @param request
     * @param response
     */
    @RequestMapping(value = "/wx_login", method = RequestMethod.GET)
    public void wxU_login(HttpServletRequest request, HttpServletResponse response){
        try {
            String state = StringUtilsEx.RandomString(32);
            redisService.set("wechat_login", state, 300);
            String scope  = "snsapi_userinfo";//静默授权  只能获取access_token和openID,流程走完即终止,snsapi_userinfo可以                                                                      //获取更详细的用户资料,比如头像、昵称、性别等
            String url = URLEncoder.encode("http://api.hestia.me/m/validate/VVIKCNMG9FP/"+"v1/user/callbackphone.do" , "utf-8");                                                                                    //CALLBACK_DOMAIN为授权回调页面域名
            String code_url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" +APPID 
                    + "&redirect_uri=" + url + "&response_type=code&scope=" + scope + "&state="+state+"#wechat_redirect";
            response.sendRedirect(code_url);                                       //可以获取code 信息并且转发到redirect_uri的地址里
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

3.回调(回调地址必须是外网可以访问的)

/**
     * 手机_授权回调
     * @param request
     * @param response
     */
    @RequestMapping(value = "/callbackphone", method = RequestMethod.GET)
    public void callbackphone(HttpServletRequest request, HttpServletResponse response){
        String code_url=null;
        String openid =null;
        try {
            String back_state = request.getParameter("state");
            String state =redisService.get("wechat_login");
            String code = request.getParameter("code");                   //授权时候,微信会吧参数传到这里
          if(!StringUtils.equalsIgnoreCase(back_state, state)){
            throw new ServiceException("请求无效!");
          }
          String keys = "wechat_login_code"+code;
          if(redisService.exists(keys)){
               openid = redisService.get(keys);
          }else{
            String access_token_url = "https://api.weixin.qq.com/sns/oauth2/access_token"+"?appid=" + APPID+ "&secret=" + AppSecret + "&code=" + code + "&grant_type=authorization_code";
            String access_token_str;
                access_token_str = httpAPIService.doGet(access_token_url);
                logger.info("----------->> access_token_str:"+access_token_str);
                //logger.info("access_token_str:{},access_token_str:{}",access_token_str,access_token_str);
                if(StringUtils.isBlank(access_token_str)){throw new ServiceException("微信授权访问通讯异常!");}
                
                Map tokenmap = JSONUtilsEx.deserialize(access_token_str, Map.class);
                if(tokenmap.get("errcode") != null){
                    throw new ServiceException("获取token失败:"+ObjectUtils.defaultIfNull(tokenmap.get("errmsg"), ""));
                }
                openid = String.valueOf(tokenmap.get("openid"));
                String token = String.valueOf(tokenmap.get("access_token"));
                Map<String, String> info = new HashMap<String, String>();
                info.put("openid", openid);
                info.put("token", token);
                redisService.set(keys, openid, 60);
                String key = "wechat_login_user"+openid;
                redisService.set(key, JSONUtilsEx.serialize(info), 300);
          }
              code_url =http://192.168.1.79:8090/mywx.shtml?code={code}&openid={openid}&token={token}

 //code_url = Infourl.replaceAll("\\{openid\\}", openid);

Map<String, String> paramMap = new HashMap<String, String>();   
                    
                        paramMap.put("openid", res.get("openid").toString());
                        paramMap.put("token", res.get("access_token").toString());

             

response.sendRedirect(CommonUtilsEx.parseByExp("\\{(.*?)\\}",url,paramMap).replaceAll("\\{(.*?)\\}", ""));
               response.sendRedirect(code_url);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }

4.页面接收token ,openid 

mywx.shtml

$(function(){

    var openid = f_GetQueryString("openid");
    var token = f_GetQueryString("token");

    if(code && openid){

        f_login(openid, token);
    }

});

function f_GetQueryString(name){
        var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
        var r = window.location.search.substr(1).match(reg);
        if(r!=null)return  unescape(r[2]); return null;
}

然后登录

function f_login(v_openid,v_token){

     $.ajax({
        url:"http://api.hsjsns.com/ser/v1/user/login",//在这接口根据v_openid,v_token 调用微信接口获取用户信息
        contentType:"application/json",
        type:"post",
        data:JSON.stringify({account:v_openid,pwd:v_token,appid:"H5WG",utype:"U_WX"}),
        dataType: "json",
        //headers: {"Content-Type":"application/json;charset=UTF-8"}, 
        success: function(data){
            console.log(data);
            if(data.code==0){
                alert(JSON.stringify(data));
                var exdate=new Date();
                exdate.setDate(exdate.getDate()+3);
                CookieUtil.set('hsj_login',(data.data.userId+"_"+data.data.token),exdate.toGMTString(),"","/");
                //var v_token=CookieUtil.get('hsj_login',"");
                // console.log(v_token);
                window.top.location.href="my.shtml";
            }
        }
        }); 
}

*******************************************

工具

public class JSONUtilsEx {

    private static ObjectMapper mapper = new ObjectMapper();

    static {

        // 设定JSON转化日期的格式
        mapper.setDateFormat(new SimpleDateFormat(DateUtilsEx.DATE_FORMAT_SEC));
        mapper.setSerializationInclusion(Include.NON_NULL);

        // TODO 看是否能转话字典表数据,不行的话只能在前台转化
        // mapper.setFilters(filterProvider);
    }

    /**
     * 对象序列化成JSON字符串
     * @param obj
     * @return
     * @throws ServiceException 
     */
    public static String serialize(Object obj) {

        StringWriter writer = null;

        try {
            writer = new StringWriter();
            mapper.writeValue(writer, obj);
            writer.close();
        } catch (Exception e) {
            throw new ServiceException("JSON序列化结果异常:" + e.getMessage());
        }

        return writer.toString();
    }

    /**
     * JSON字符串反序列化成对象
     * @param jsonStr
     * @param clazz
     * @return
     * @throws ServiceException 
     */
    public static <T> T deserialize(String jsonStr, Class<T> clazz) throws ServiceException {

        if (StringUtils.isEmpty(jsonStr)) {
            return null;
        }

        try {
            return mapper.readValue(jsonStr.replace("\n", ""), clazz);
        } catch (Exception e) {
            throw new ServiceException("JSON反序列化结果异常:" + e.getMessage());
        }
    }

}

************************************************************

public class VerifyUtilsEx {
    
    static String KEY = "RVqq0cifgVJCfeCSxnWU6LoyGIpwYOa6";
    static long TIMESTAMP = 5*60;                        //时间戳5分钟 5*60
    
    /**
     * 接口必要参数签名验证
     * @return String
     * @throws UnsupportedEncodingException 
     */
    public static String verifyParam(HttpServletRequest request,String[] args) throws UnsupportedEncodingException{
        Map params = transToMAP(request.getParameterMap());
        return verifyData(params,args);
    }
    
    public static String verifyData(Map<String, String> data,String[] args) throws UnsupportedEncodingException{
        
        String sign = "";
        String arg_cnt = "";
        String msg = "";
        
        if(data == null || data.isEmpty()) return "没有检索到参数!";
        
        for(String arg : args){
            
            if(data.keySet().contains(arg)){
                if(data.get(arg)==null || !StringUtils.hasText(String.valueOf(data.get(arg)))){
                    msg = "参数【"+arg+"】未明确,请确认!";
                    break;
                }
                
                if("sign".equals(arg)){
                    sign = String.valueOf(data.get(arg));
                }
                
                if("ts".equals(arg)){
                    long systime = System.currentTimeMillis()/1000;
                    
                    long v_ts = Long.parseLong(data.get(arg));
                    //时间戳校验
                    if(Math.abs(systime-v_ts) > TIMESTAMP){
                        msg = "请求超出有效期!";
                        break;
                    }
                }
            }else{
                msg = "参数【"+arg+"】未明确,请确认!";
                break;
            }
        }
        
        //参数都已明确并需要签名验证
        if(StringUtils.hasText(sign) && !StringUtils.hasText(msg)){
            for(String arg1 : args){
                if(!"sign".equals(arg1)){
                    arg_cnt += String.valueOf(data.get(arg1));
                }
            }

            //System.out.println(URLEncoder.encode(arg_cnt+KEY,"utf-8"));
            String v_sign = Md5UtilsEx.getMD5Str(URLEncoder.encode(arg_cnt+KEY,"utf-8").toLowerCase());
            //System.out.println(v_sign);
            if(!sign.toLowerCase().equals(v_sign.toLowerCase())){
                msg = "校验码错误!";
            }
        }
        
        return msg;
    }
    
    private static Map transToMAP(Map parameterMap) throws UnsupportedEncodingException{
          // 返回值Map
          Map returnMap = new HashMap();
          Iterator entries = parameterMap.entrySet().iterator();
          Map.Entry entry;
          String name = "";
          String value = "";
          while (entries.hasNext()) {
              entry = (Map.Entry) entries.next();
              name = (String) entry.getKey();
              Object valueObj = entry.getValue();
              if(null == valueObj){
                  value = "";
              }else if(valueObj instanceof String[]){
                  String[] values = (String[])valueObj;
                  for(int i=0;i<values.length;i++){
                      value = values[i] + ",";
                  }
                  value = value.substring(0, value.length()-1);
              }else{
                  value = valueObj.toString();
              }
              System.out.println(value);
              returnMap.put(name, value);
          }
          return  returnMap;
      }

}

*****************************************************************************

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值