1.注册微信开放平台https://open.weixin.qq.com,一定要清楚微信开放平台和微信公众平台是分别独立的,不能共用。
2.登录进入——管理中心,网站应用,创建网站应用。填写申请,企业还要盖章,然后设置域名,最后交300元保护费。成功通过验证。获得appid和appSecret两个参数。
3.现在可以在web端里写登录控制器了。
4.微信网站登录的文档在https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=41ab5f757248bbbdcc2aad1a6d52b49fdc19579e&lang=zh_CN。
以上前3步是公司去微信那边注册用的。主要是获取两个参数 appid (应用唯一标识)和 appsecret (是应用接口使用密钥) 还有就是指定我们注册时,
对应的域名,方便我们以后进行域名映射跳转。 第4不是微信官方文档我们的会和微信交互3次,这三个连接都是从文档上拿的记得好好看。
整体流程就是:
1. 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;
2. 通过code参数加上AppID和AppSecret等,通过API换取access_token;
3. 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。
==贴代码
1.第一步
** *@ClassName 读取微信配置文件中的参数 *@Description TODD *@AUTHOR sh-wangbs *@Date 2019/1/3115:00 *@Version 1.0 **/ @Configuration @PropertySource(value = "classpath:application.properties") @Data public class WeChatConfig { //开放平台appid @Value("${wxopen.appid}") private String openAppid; //开放平台appsecret @Value("${wxopen.appsecret}") private String openAppsecret; //重定向第三方平台的地址 @Value("${wxopen.redirect_url}") private String openRedirectUrl; //微信开放平台二维码连接(从微信官方文档拿的第一个连接) private final static String OPEN_QRCODE_URL = "https://open.weixin.qq.com/connect/qrconnect?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_login&state=%s#wechat_redirect"; // 开放平台获取access_token地址(从微信官方文档拿的第二个连接) private final static String OPEN_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code"; //获取用户信息(从微信官方文档拿的第三个连接) private final static String OPEN_USER_INFO_URL ="https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN"; public static String getOpenUserInfoUrl() { return OPEN_USER_INFO_URL; } public static String getOpenQrcodeUrl() { return OPEN_QRCODE_URL; } public static String getOpenAccessTokenUrl() { return OPEN_ACCESS_TOKEN_URL; } } 2.第二步
/*** * @Description: 用户生成用户能扫一扫的微信二维码 * @Param: [accessPage] * @return: cn.unicom.com.utils.JsonData * @author: wangbs * @create: 2019/2/1 8:52 */ @GetMapping("login_url") @ResponseBody public JsonData loginUrl(@RequestParam(value = "access_page",required = true)String accessPage) throws UnsupportedEncodingException { //获取跳转到我们自己项目的重定向地址 String redirectUrl = weChatConfig.getOpenRedirectUrl(); String callbackUrl = URLEncoder.encode(redirectUrl,"GBK"); //进行编码 String qrcodeUrl = String.format(weChatConfig.getOpenQrcodeUrl(), weChatConfig.getOpenAppid(), callbackUrl, accessPage); return JsonData.buildSuccess(qrcodeUrl); } 3.第三步
/*** * @Description: 我们自己网站用于回调的借口 * @Param: [code=>用户的唯一标识, state=》我们自己设定带的参数(比较带用户当前扫码的地址), response] * @return: cn.unicom.com.utils.JsonData * @author: wangbs * @create: 2019/2/1 14:20 */ @GetMapping("callback") @ResponseBody public JsonData callback(@RequestParam(value = "code",required = true) String code, String state, HttpServletResponse response){ //保存用户 微信一键登录的(剩下的两次交互写在了service) User user = userService.saveWeChatUser(code); //判断用户是否成功登陆 不为null 用户登录成功,做你该做的业务,为null 用户没登录。 if(user != null){ //生成jwt String token = JwtUtils.geneJsonWebToken(user); // state 当前用户的页面地址,需要拼接 http:// 这样才不会站内跳转 response.sendRedirect(state+"?token="+token+"&head_img="+user.getHeadImg()+"&name="+URLEncoder.encode(user.getName(),"UTF-8")); } return null ; } a.service
@Override public User saveWeChatUser(String code) { //获取和微信客户端的第二次交互的url(记得带上appid+appsecret+code)
String accessTokenUrl = String.format(WeChatConfig.getOpenAccessTokenUrl(),weChatConfig.getOpenAppid(),weChatConfig.getOpenAppsecret(),code); //和微信客户端的第二次交互,获取appid和access_token Map<String, Object> baseMap = HttpUtils.doGet(accessTokenUrl); //access_token openid if(baseMap == null || baseMap.isEmpty()){ return null; } String accessToken = (String)baseMap.get("access_token"); String openId = (String) baseMap.get("openid"); //在这里用户已经登陆了,我们首先拿到用户的唯一标识openid 去我们的user表中查,该用户是否存在 User userByOptionId = userMapper.findUserByOptionId(openId); //用户信息在我们数据库有了 直接放心 if (userByOptionId!=null){ return userByOptionId; } //用户第一次通过扫一扫登录我们系统 //获取和微信客户端的第三次交互的连接 String userInfoUrl = String.format(WeChatConfig.getOpenUserInfoUrl(),accessToken,openId);
//通过第三次访问微信连接 获得 用户信息
Map<String ,Object> baseUserMap = HttpUtils.doGet(userInfoUrl); if(baseUserMap == null || baseUserMap.isEmpty()){ return null; } String nickname = (String)baseUserMap.get("nickname"); Double sexTemp = (Double) baseUserMap.get("sex"); int sex = sexTemp.intValue(); String province = (String)baseUserMap.get("province"); String city = (String)baseUserMap.get("city"); String country = (String)baseUserMap.get("country"); String headimgurl = (String)baseUserMap.get("headimgurl"); StringBuilder sb = new StringBuilder(country).append("||").append(province).append("||").append(city); String finalAddress = sb.toString(); try { //解决乱码 nickname = new String(nickname.getBytes("ISO-8859-1"), "UTF-8"); finalAddress = new String(finalAddress.getBytes("ISO-8859-1"), "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } //封装用户信息保存用户 User user=new User(); user.setOpenid(openId); user.setName(nickname); user.setSex(sex); user.setHeadImg(headimgurl); user.setCreateTime(new Date()); user.setCity(finalAddress); userMapper.saveUser(user); return user;
}复制下方date中的连接去浏览器(就是二维码)
用户扫一扫就登陆了。
//上面代码亲自测试的 有效 缺失点实体类啥的自己补上。 还有上面提到的域名映射的问题测试的话可以用(ngrock) http://ngrok.ciqiuwl.cn/ 这个工具能够实现本地ip和域名的映射。别人就能通过外网访问你的域名从而能访问你的ip了。这软件只能自己练习用,不能干非法的事。
Copyright © 2021.自由园 All rights reserved. 鲁ICP备16000743号 滇公网安备 53010302001103号