Springboot网站第三方登录 微信登录
微信开放平台接入,官网:https://open.weixin.qq.com,在官网注册并添加应用后即可获得APP_ID和APP_SECRET。
步骤一:创建一个继承AuthService的接口,WeChatAuthService,如下
publicinterfaceWeChatAuthServiceextendsAuthService{ publicJSONObjectgetUserInfo(StringaccessToken,StringopenId); }
步骤二:WeChatService的具体实现如下
@Service publicclassWeChatAuthServiceImplextendsDefaultAuthServiceImplimplementsWeChatAuthService{ privateLoggerlogger=LoggerFactory.getLogger(WeChatAuthServiceImpl.class); //请求此地址即跳转到二维码登录界面 privatestaticfinalStringAUTHORIZATION_URL= "https://open.weixin.qq.com/connect/qrconnect?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect"; //获取用户openid和access——toke的URL privatestaticfinalStringACCESSTOKE_OPENID_URL= "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code"; privatestaticfinalStringREFRESH_TOKEN_URL= "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s"; privatestaticfinalStringUSER_INFO_URL= "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN"; privatestaticfinalStringAPP_ID="xxxxxx"; privatestaticfinalStringAPP_SECRET="xxxxxx"; privatestaticfinalStringSCOPE="snsapi_login"; privateStringcallbackUrl="https://www.xxx.cn/auth/wechat";//回调域名 @Override publicStringgetAuthorizationUrl()throwsUnsupportedEncodingException{ callbackUrl=URLEncoder.encode(callbackUrl,"utf-8"); Stringurl=String.format(AUTHORIZATION_URL,APP_ID,callbackUrl,SCOPE,System.currentTimeMillis()); returnurl; } @Override publicStringgetAccessToken(Stringcode){ Stringurl=String.format(ACCESSTOKE_OPENID_URL,APP_ID,APP_SECRET,code); UriComponentsBuilderbuilder=UriComponentsBuilder.fromHttpUrl(url); URIuri=builder.build().encode().toUri(); Stringresp=getRestTemplate().getForObject(uri,String.class); logger.error("getAccessTokenresp="+resp); if(resp.contains("openid")){ JSONObjectjsonObject=JSONObject.parseObject(resp); Stringaccess_token=jsonObject.getString("access_token"); StringopenId=jsonObject.getString("openid");; JSONObjectres=newJSONObject(); res.put("access_token",access_token); res.put("openId",openId); res.put("refresh_token",jsonObject.getString("refresh_token")); returnres.toJSONString(); }else{ thrownewServiceException("获取token失败,msg="+resp); } } //微信接口中,token和openId是一起返回,故此方法不需实现 @Override publicStringgetOpenId(StringaccessToken){ returnnull; } @Override publicJSONObjectgetUserInfo(StringaccessToken,StringopenId){ Stringurl=String.format(USER_INFO_URL,accessToken,openId); UriComponentsBuilderbuilder=UriComponentsBuilder.fromHttpUrl(url); URIuri=builder.build().encode().toUri(); Stringresp=getRestTemplate().getForObject(uri,String.class); logger.error("getUserInforesp="+resp); if(resp.contains("errcode")){ thrownewServiceException("获取用户信息错误,msg="+resp); }else{ JSONObjectdata=JSONObject.parseObject(resp); JSONObjectresult=newJSONObject(); result.put("id",data.getString("unionid")); result.put("nickName",data.getString("nickname")); result.put("avatar",data.getString("headimgurl")); returnresult; } } //微信的token只有2小时的有效期,过时需要重新获取,所以官方提供了 //根据refresh_token刷新获取token的方法,本项目仅仅是获取用户 //信息,并将信息存入库,所以两个小时也已经足够了 @Override publicStringrefreshToken(Stringrefresh_token){ Stringurl=String.format(REFRESH_TOKEN_URL,APP_ID,refresh_token); UriComponentsBuilderbuilder=UriComponentsBuilder.fromHttpUrl(url); URIuri=builder.build().encode().toUri(); ResponseEntityresp=getRestTemplate().getForEntity(uri,JSONObject.class); JSONObjectjsonObject=resp.getBody(); Stringaccess_token=jsonObject.getString("access_token"); returnaccess_token; } }
步骤三:
在Controller中调用,代码如下:
@RequestMapping(value="/wxLoginPage",method=RequestMethod.GET) publicJSONObjectwxLoginPage()throwsException{ Stringuri=weChatAuthService.getAuthorizationUrl(); returnloginPage(uri); } @RequestMapping(value="/wechat") publicvoidcallback(Stringcode,HttpServletRequestrequest,HttpServletResponseresponse)throwsException{ Stringresult=weChatAuthService.getAccessToken(code); JSONObjectjsonObject=JSONObject.parseObject(result); Stringaccess_token=jsonObject.getString("access_token"); StringopenId=jsonObject.getString("openId"); //Stringrefresh_token=jsonObject.getString("refresh_token"); //保存access_token到cookie,两小时过期 CookieaccessTokencookie=newCookie("accessToken",access_token); accessTokencookie.setMaxAge(60*2); response.addCookie(accessTokencookie); CookieopenIdCookie=newCookie("openId",openId); openIdCookie.setMaxAge(60*2); response.addCookie(openIdCookie); //根据openId判断用户是否已经登陆过 KmsUseruser=userService.getUserByCondition(openId); if(user==null){ response.sendRedirect(request.getContextPath()+"/student/html/index.min.html#/bind?type="+Constants.LOGIN_TYPE_WECHAT); }else{ //如果用户已存在,则直接登录 response.sendRedirect(request.getContextPath()+"/student/html/index.min.html#/app/home?open_id="+openId); } }
步骤四:
前台js中,先请求auth/wxLoginPage,获取授权地址,等用户授权后会回调/auth/wechat,在此方法中进行逻辑处理即可。
遇到过的坑:
1.在微信官网中配置回调域名的时候,不需要些http或https协议,只需要写上域即可,例如http://baidu.com,只需要填写baidu.com即可,如果是想要跳转到项目下面的某个Controller的某个方法中,如baidu.com/auth/wechat,配置的时候也只需要配baidu.com,不需要指定后面的auth/wechat,后面的地址在代码中配置回调的地址的时候写上即可,代码中应该配置为https://baidu.com/auth/wechat
2.在跳转到授权二维码界面的时候,会遇到有的时候二维码出不来的状况,这是因为代码中的回调地址的问题,按照上面代码中的方式配置应该是没有问题的
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。