微信联合登录

来源:互联网 发布:uc文书 知乎 编辑:程序博客网 时间:2024/04/29 01:09

参考资料: https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=&lang=zh_CN

开发的准备工作:

注册一个开放平台的账号,用来创建一个网站应用,该网站应用通过审核后获得AppID和AppSecret。比如www.yunke.com需要微信登录功能。首先用邮箱注册在微信开发平台注册一个账号,然后为www.yunke.com创建一个网站应用,审批时用要公司的运营信息。审批通过后要开启登录功能。

项目需求:

网站登录页面点击微信图标,调转到微信二维码授权页面,用户扫描二维码并授权后登录网站。

开发:

第一步:发送请求获取code

API代码:

/** * 请求微信Code,显示二维码页,用户授权后调整到第三方redirectUri制定的页面 * @param baseUrl 必须 微信路径获取Code地址,例:https://open.weixin.qq.com/connect/qrconnect * @param appid 必须  应用唯一标识,在微信开放平台提交应用审核通过后获得 * @param redirectUri 必须 第三方重定向地址 * @param code 必须 填code * @param scope 必须 应用授权作用域,拥有多个作用域用逗号(,)分隔, * 网页应用目前仅填写snsapi_login即可 * @param state 不必须 用于保持请求和回调的状态, * 授权请求后原样带回给第三方。 * 该参数可用于防止csrf攻击(跨站请求伪造攻击), * 建议第三方带上该参数, * 可设置为简单的随机数加session进行校验 * 创建时间:2016年11月2日 下午3:07:32 */public boolean toLoginPage(String baseUrl,String appid,String redirectUri,String code,String scope,String state,HttpServletResponse response){try {String redirectUriCode = URLEncoder.encode(redirectUri,"utf-8");baseUrl+="?appid="+appid+"&redirect_uri="+redirectUriCode+"&response_type="+code+"&scope="+scope+"&state="+state+"";try {response.sendRedirect(baseUrl);} catch (IOException e) {log.error("URLEncoder重定向地址失败,请求取消");e.printStackTrace();return false;}return true;} catch (UnsupportedEncodingException e) {log.error("URLEncoder重定向地址失败,请求取消");e.printStackTrace();return false;}}

Controller代码:

@RequestMapping(value = "/toLogin")public void weixinLogin(HttpServletRequest request,HttpServletResponse response){String appid=PropertiesUtils.getProperty("system.weixin.appid");int serverPost = request.getServerPort();String basePath = null;    if(serverPost==80){    basePath = request.getScheme()+"://"+request.getServerName()+request.getContextPath();    }else{    basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath();    }String redirectUri=basePath+"/weixin/loginProcess";String code="code";String scope="snsapi_login";String state=MyTools.generateString(20);//20个随机数HttpSession session = request.getSession();session.setAttribute("weixincode", state);String baseUrl="https://open.weixin.qq.com/connect/qrconnect";weixinHelper.toLoginPage(baseUrl, appid, redirectUri, code, scope, state,response);}

URL如下:

https://open.weixin.qq.com/connect/qrconnect?appid=***@_@***&redirect_uri=http%3A%2F%2Fwww.yunke.com%2Fweixin%2FloginProcess&response_type=code&scope=snsapi_login&state=k1GCnnl7xXH5skYkwh5Q
注意事项:
1.appid确实是创建网站后获取的,只要不填写错误,都能跳转到二维码页。

2.redirect_uri路径要写全,不要写成相对路径。路径要编码。

3.state防跨站攻击,数值可以随机生成

第二步:根据code获取Token,根据Token获取用户信息。

API代码:

/** * 通过code获取access_token * @param baseUrl 必须 获取令牌地址,例:https://api.weixin.qq.com/sns/oauth2/access_token * @param appid 必须  应用唯一标识,在微信开放平台提交应用审核通过后获得 * @param secret 必须 应用密钥AppSecret,在微信开放平台提交应用审核通过后获得 * @param code 必须 填写toLoginPage重定向后获取的code参数 * @param grantType 必须 填authorization_code * @return 错误返回{"errcode":40029,"errmsg":"invalid code"} * 正确返回{ "access_token":"ACCESS_TOKEN", "expires_in":7200,"refresh_token":"REFRESH_TOKEN","openid":"OPENID", "scope":"SCOPE","unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"} * 创建时间:2016年11月2日 下午4:19:32 */public JSONObject getAccessToken(String baseUrl,String appid,String secret,String code,String grantType){baseUrl+="?appid="+appid+"&secret="+secret+"&code="+code+"&grant_type="+grantType;String resultJson=HttpHelper.doGetNoAuth(baseUrl);System.out.println(resultJson);return JSONObject.parseObject(resultJson);}



/** * 获取用户个人信息 * @param baseUrl 必须 获取用户个人信息地址 * @param accessToken 必须 调用接口凭证 * @param openid 必须 普通用户的标识,对当前开发者帐号唯一 * @param lang 不必须 国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语,默认为zh-CN * @return 错误时返回{"errcode":40003,"errmsg":"invalid openid"} * 真确时返回{"openid":"OPENID","nickname":"NICKNAME","sex":1,"province":"PROVINCE","city":"CITY","country":"COUNTRY","headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0","privilege":["PRIVILEGE1", "PRIVILEGE2"],"unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"} * 创建时间:2016年11月2日 下午5:44:14 */public JSONObject getUserInfo(String baseUrl,String accessToken,String openid,String lang){baseUrl+="?openid="+openid+"&access_token="+accessToken+"&lang="+lang;String resultJson=HttpHelper.doGetNoAuth(baseUrl);return JSONObject.parseObject(resultJson);}

Controller代码:

@RequestMapping(value = "/loginProcess")public ModelAndView LoginProcess( HttpServletRequest request){ModelAndView mav=new ModelAndView();String code=request.getParameter("code");String stateWeiXin=request.getParameter("state");String state=(String)request.getSession().getAttribute("weixincode");request.getSession().removeAttribute("weixincode");/*防止跨站攻击*/if(null==stateWeiXin||null==state||!stateWeiXin.trim().equalsIgnoreCase(state.trim())){mav.setViewName("/error404");mav.addObject("msg", "疑似跨站攻击");return mav;}/*判断第一步是否得到Code*/if(MyTools.isEmptyStr(code)){//登录失败处理mav.setViewName("/error404");return mav;}else{String appid=PropertiesUtils.getProperty("system.weixin.appid");String secret=PropertiesUtils.getProperty("system.weixin.appSecret");String getTokenUrl="https://api.weixin.qq.com/sns/oauth2/access_token";String getUserInfoUrl="https://api.weixin.qq.com/sns/userinfo";JSONObject tokenInfo=weixinHelper.getAccessToken(getTokenUrl, appid, secret, code, "authorization_code");if(null==tokenInfo){mav.setViewName("/error404");mav.addObject("msg", "HTTP请求出错!");return mav;}if(tokenInfo.containsKey("errcode")){/*获取Token失败处理*///登录失败处理mav.setViewName("/error404");mav.addObject("msg", tokenInfo.get("errmsg"));return mav;}else{/*用Token获取用户信息*/String accessToken=tokenInfo.getString("access_token");String openid=tokenInfo.getString("openid");JSONObject userInfo=weixinHelper.getUserInfo(getUserInfoUrl, accessToken, openid, "zh_CN");if(userInfo.containsKey("errcode")){/*获取信息失败*/mav.setViewName("/error404");mav.addObject("msg", tokenInfo.get("errmsg"));return mav;}else{/*获取信息成功*///保存用户UserInfo user=new UserInfo();user.setUid(userInfo.getString("unionid"));user.setName(userInfo.getString("nickname"));user.setWeiXinId(userInfo.getString("unionid"));user.setCreateDate(new Date());user.setEnabled(1);user.setType(1);user.setRegisterSource(3);user.setRegisterCode(MyTools.generateString(30));userService.saveUserInfo(user);//登录处理InsideUsernamePasswordToken token = new InsideUsernamePasswordToken();//****#######@@@@@@@@@@@处理登录的代码token.setRememberMe(false);Subject subject = SecurityUtils.getSubject();subject.login(token);mav.setViewName("redirect:/index");return mav;}}}}

URL:

https://open.weixin.qq.com/connect/qrconnect?appid=****@_@***&redirect_uri=http%3A%2F%2Fwww.yunke.com%2Fweixin%2FloginProcess&response_type=code&scope=snsapi_login&state=9kuspa8kmjSfCCD51Wia

注意:

1.secret长期不用回自动重置,有可能出现invalid appsecret报错

2.redirect_uri为第一步中的redirect_uri

3.token的有效期为2h,必要时要刷新token。

0 0