PC端微信QQ第三方登录

微信第三方登录实现原理准备工作

参考微信开放平台:https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html

准备工作
网站应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统。
在进行微信OAuth2.在进行微信OAuth2.0授权登录接入之前,在微信开放平台注册开发者帐号,并拥有一个已审核通过的网站应用,并获得相应的AppID和AppSecret,申请微信登录且通过审核后,可开始接入流程。

授权流程说明
微信OAuth2.0授权登录让微信用户使用微信身份安全登录第三方应用或网站,在微信用户授权登录已接入微信OAuth2.0的第三方应用后,第三方可以获取到用户的接口调用凭证(access_token),通过access_token可以进行微信开放平台授权关系接口调用,从而可实现获取微信用户基本开放信息和帮助用户实现基础开放功能等。
微信OAuth2.0授权登录目前支持authorization_code模式,适用于拥有server端的应用授权。该模式整体流程为:

第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;
通过code参数加上AppID和AppSecret等,通过API换取access_token;
通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。

第一步:请求CODE
第三方使用网站应用授权登录前请注意已获取相应网页授权作用域(scope=snsapi_login),则可以通过在PC端打开以下链接:
https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
若提示“该链接无法访问”,请检查参数是否填写错误,如redirect_uri的域名与审核时填写的授权域名不一致或scope不为snsapi_login。

参数说明

参数 是否必须 说明
appid 是 应用唯一标识
redirect_uri 是 请使用urlEncode对链接进行处理
response_type 是 填code
scope 是 应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即
state 否 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验
返回说明

用户允许授权后,将会重定向到redirect_uri的网址上,并且带上code和state参数
redirect_uri?code=CODE&state=STATE
若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数
redirect_uri?state=STATE


代码如下:

1.前台按钮跳转到后台

	/**网页点击微信登录按钮跳转到此方法***/    
    @RequestMapping("/wxLogin")
    public void wxLogin(HttpServletRequest request,HttpServletResponse response){    	
    	String redirect_uri = PropertiesUtil.getProperty("wx_redirect_URI");//"https://pre-www.laozicloud.com/third/wxCallBack";
    	String wxAPPID= PropertiesUtil.getProperty("wx_app_ID");//微信开放平台申请的appID
    	String redirectUrl = request.getParameter("redirectUrl");//授权后的回调地址
    	/***if(StringUtils.isNotBlank(redirectUrl)){//这部分属于业务代码,根据需要添加
            WebUtil.getSession().setAttribute(SysConstant.URL, redirectUrl);
        }***/
    	//随机产生1-100的随机数
    	long r = Math.round(Math.random()*100);//随机数,增加安全性
    	try

    	{
    		response.setHeader("Access-Control-Allow-Origin", "*");  
    		  
    		response.setHeader("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");  
      
            response.setHeader("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");  
      
            response.setHeader("X-Powered-By","Jetty");  
      
    	  response.sendRedirect("https://open.weixin.qq.com/connect/qrconnect?appid="+wxAPPID+"&redirect_uri="

    	   +
    	 URLEncoder.encode(redirect_uri,"utf-8") 

    	   +
    	"&response_type=code&scope=snsapi_login"+"&state="+r+"#wechat_redirect");

    	 }
    	catch(IOException  e) {
    		e.printStackTrace();
    		System.out.println("wxLogin exception "+e.getMessage()); 
    	}
    }

2.用户授权后拿到code和state

    @RequestMapping("/wxCallBack")
    public ModelAndView wxCallBack(HttpServletRequest request,ModelMap modelMap,ModelAndView modelView,RedirectAttributes attributes,HttpServletResponse response){ 
    	//授权成功
        if(request.getParameter("code")!=null){  
            String code =  request.getParameter("code");  
            String accessTokenStr = getAccessToken(code); //根据code获取token和openId
            System.out.println("accessTokenobj:"+accessTokenStr);
            if(StringUtils.isNotBlank(accessTokenStr){  
                JSONObject returnObj = JSONObject.parseObject(accessTokenStr);  
                if (returnObj!=null){  
                    String access_token = returnObj.getString("access_token");  
                    String openId = returnObj.getString("openid");  
                    System.out.println("access_token:"+access_token+"   openId:"+openId);
                    String userInfo = getUserInfo(access_token,openId); //根据token和openId获取用户信息
                    System.out.println("userinfo:"+userInfo); 
                    /****获取到用户信息后处理页面代码***/
                    if(StringUtils.isNotBlank(userInfo)) {
          	    	  JSONObject jsonObject = JSONObject.parseObject(userInfo);
	          	      String avatar = jsonObject.getString("headimgurl");
	          	      String nickname =jsonObject.getString("nickname");
	          	      String openid =jsonObject.getString("unionid");
          		      ThirdUserVO thirdUser = new ThirdUserVO();
          		      thirdUser.setAvatar(avatar);
          		      thirdUser.setNickName(nickname);
          		      thirdUser.setOpenId(openid);        
                      thirdUser.setRegisterMethod("weixin");
          	          modelView=getModelAndView( modelView, thirdUser, request,  modelMap, attributes,response);
          	          return modelView;
          	      }else {
          	    	  
          	    	  modelMap.put("errorMsgKey", "第三方登录qq出错了");
          	          return new ModelAndView("redirect:/login", new ModelMap()); 
          	      }
                }  
            }  
  
        }else {
        	//取消授权
        	System.out.println("用户取消了授权:"); 
        	return new ModelAndView("redirect:/login", new ModelMap());
        }return new ModelAndView("redirect:/login", new ModelMap());
        
    }

3.根据code获取token和openId

 /** 
     * 获得code后获取access_token 
         { 
         "access_token":"ACCESS_TOKEN", 
         "expires_in":7200, 
         "refresh_token":"REFRESH_TOKEN", 
         "openid":"OPENID", 
         "scope":"SCOPE" 
         } 
     * @param code 
     */  
    public String getAccessToken(String code){  
        // https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code  
        try{  
        	String wxAPPID = PropertiesUtil.getProperty("wx_app_ID");
        	String wxSECRET = PropertiesUtil.getProperty("wx_secret");
            String url = "https://api.weixin.qq.com/sns/oauth2/access_token";  
            String param = "appid="+wxAPPID+"&secret="+wxSECRET+"&code="+code+"&grant_type=authorization_code";  
            return sendGet(url,param);  
        }catch (Exception e){  
            e.printStackTrace();  
        }  
        return null;  
    }  
  
 /** 
     * 发送GET请求 
     * @param url 
     * @param param 
     * @return 
     */  
    public static String sendGet(String url, String param) {  
        String result = "";  
        BufferedReader in = null;  
        try {  
            String urlNameString = url + "?" + param;  
            URL realUrl = new URL(urlNameString);  
            URLConnection connection = realUrl.openConnection();  
            connection.setRequestProperty("accept", "*/*");  
            connection.setRequestProperty("connection", "Keep-Alive");  
            connection.setRequestProperty("user-agent",  
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");  
            connection.connect();  
            Map<String, List<String>> map = connection.getHeaderFields();  
            for (String key : map.keySet()) {  
                System.out.println(key + "--->" + map.get(key));  
            }  
            in = new BufferedReader(new InputStreamReader(  
                    connection.getInputStream()));  
            String line;  
            while ((line = in.readLine()) != null) {  
                result += line;  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        finally {  
            try {  
                if (in != null) {  
                    in.close();  
                }  
            } catch (Exception e2) {  
                e2.printStackTrace();  
            }  
        }  
        return result;  
    }  

4.根据token和openId获取用户信息

    public String getUserInfo(String access_token,String openId){  
        return sendGet("https://api.weixin.qq.com/sns/userinfo","access_token="+access_token+"&openid="+openId);  
    }  

---------------微信登录的到此结束,以下是qq登录的---------------

在QQ互联参考文档:https://wiki.connect.qq.com/%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C_oauth2-0

1.点击QQ按钮后跳转到此方法

 @RequestMapping(value="/qqlogin")
    public void qqlogin(HttpServletRequest request,HttpServletResponse response){
        String redirectUrl = request.getParameter("redirectUrl");
        if(StringUtils.isNotBlank(redirectUrl)){
            WebUtil.getSession().setAttribute(SysConstant.URL, redirectUrl);
        }
    	 response.setContentType("text/html;charset=utf-8");
        	String state = UUID.randomUUID().toString().replace("-", "").toUpperCase();
             
			try {
				response.sendRedirect(String.format(AUTHORIZE_URL, PropertiesUtil.getProperty("qq_app_ID"),URLEncoder.encode(PropertiesUtil.getProperty("qq_redirect_URI"), "UTF-8"),state,"get_user_info"));
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
         
        
    }

2.授权后回调的方法

    @RequestMapping(value="/qqloginCallBack")
  public ModelAndView qqloginCallBack(ModelAndView modelView,HttpServletRequest request,ModelMap modelMap,RedirectAttributes attributes,HttpServletResponse response) throws IOException {
//        modelView=getModelAndView( modelView, new ThirdUserVO(), request,  modelMap, attributes);

    	String code = request.getParameter("code");
    	if(StringUtils.isEmpty(code)) {
    		return initErrorMsg(modelView);
    	}
    	System.out.println("code:"+code);
    	String access_token = getAccessToken( PropertiesUtil.getProperty("qq_app_ID"), PropertiesUtil.getProperty("qq_app_KEY") , code, PropertiesUtil.getProperty("qq_redirect_URI"));
		if("error".equals(access_token)) {
			return initErrorMsg(modelView);
		} 
    	String openid = getOpenId(access_token);
		  System.out.println("openid:"+openid);
	      String content = HttpClientUtil.get(getGetUserInfoUrl(access_token,PropertiesUtil.getProperty("qq_app_ID"),openid), null);
	      System.out.println("content:"+content);
	      if(StringUtils.isNotBlank(content)) {
	    	  JSONObject jsonObject = JSONObject.parseObject(content);
		      ThirdUserVO thirdUser = new ThirdUserVO();
		      thirdUser.setAvatar(jsonObject.getString("figureurl_qq_1"));
		      thirdUser.setNickName(jsonObject.getString("nickname"));
		      thirdUser.setOpenId(openid);        
              thirdUser.setRegisterMethod("qq");
	          modelView=getModelAndView( modelView, thirdUser, request,  modelMap, attributes,response);
	          return modelView;
	      }else {
//	    	  modelMap.put("errorMsgKey", "第三方登录qq出错了");
//	          return new ModelAndView("redirect:/login", new ModelMap()); 
	    	  return initErrorMsg(modelView);
	      }
          
  }

完整代码:

链接: https://pan.baidu.com/s/1cqIgYUThZ3YrYjP-kQerDA 提取码: 9b4u

 

有问题欢迎留言探讨!

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值