springmvc实现微信扫码登陆网站功能

微信扫码登陆过程

  1. 在微信开放平台上注册并创建网站应用,等待审核;需提供公司章及域名等信息

 

  1. 审核通过后获取AppIDAppSecret
  2. 思考流程:
    1. 首先思考如何生成二维码
    2. 扫码后的情况
      • 用户未绑定网站时,跳转到绑定界面
      • 用户绑定过网站,扫码后直接登陆并跳转到首页
    3. 用户绑定账号的问题:
      • 该账号已绑定过,需要提示
      • 该微信已绑定过(不需要想了,扫码直接登陆了,不会跳转到绑定界面)
    4. 用户解绑:
      • 在个人中心添加对微信绑定的管理,解绑就是将微信获取到的unionid置空即可。
  3. 编码思路:

      注意:开放平台只有绑定公众号才可以获取到unionid,这里使用的是unionid,如果没有则用openid。

扫码实现流程
扫码流程

     3.1 生成二维码

@GetMapping("wechat")
public void Wechat(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    String url = "https://open.weixin.qq.com/connect/qrconnect?appid=" + WeixinUtil.KAPPID
            + "&redirect_uri=" + URLEncoder.encode(WeixinUtil.CORE_REDIRECT_URL)
            + "&response_type=code"
            + "&scope=snsapi_login&state=STATE#wechat_redirect";//返回需要扫码的二维码html
    resp.sendRedirect(url);
   }

WeixinUtil.KAPPID公众平台获取的appid
WeixinUtil.CORE_REDIRECT_URL扫码后需要跳转到处理的回调方法,这里是http://域名/项目名/路由/callBack

       3.2 扫码后处理的回调

//扫码后回调
@RequestMapping(value = "/callBack")
@ResponseBody
protected ModelAndView callBack(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String code = req.getParameter("code");
    String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + WeixinUtil.KAPPID
            + "&secret=" + WeixinUtil.KAPPSECRET
            + "&code=" + code
            + "&grant_type=authorization_code";
    net.sf.json.JSONObject jsonObject = AuthUtil.doGetJson(url);
    String openid = jsonObject.getString("openid");
    String token = jsonObject.getString("access_token");
    String infoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + token
            + "&openid=" + openid
            + "&lang=zh_CN";
    JSONObject userInfo = AuthUtil.doGetJson(infoUrl);
    //1.使用微信用户信息直接登录,无需注册和绑定
    System.out.println(userInfo);

//当前开放平台与公众号绑定,可以获取到用户unionid,否则获取不到。
    String unionid = userInfo.getString("unionid");
    //2.将微信与当前系统的账号进行绑定
    List<User> listLogin = userService.findByOpenid(unionid);//查询当前unionid是否被绑定过
    System.out.println("listLogin==" + listLogin);
    if (listLogin.size() > 0) {
        //已经存在直接登陆,跳转到首页,此处是shiro登陆代码,可更换为自己的默认登陆形式
        Subject user = SecurityUtils.getSubject();
        String name = listLogin.get(0).getName();
        VXToken usertoken = new VXToken(name, listLogin.get(0).getP_password(), name);
        usertoken.setRememberMe(false);
        try {
            user.login(usertoken);
        } catch (Exception e) {
            throw new RuntimeException("账号登陆异常!请联系管理员", e);
        }
        System.out.println("openid--------------------------------" + openid);
        System.out.println("unionid------------------------------" + unionid);
        req.getRequestDispatcher("/home").forward(req, resp);
        return null;
    } else {
        //不存在跳转到绑定页面
        System.out.println("openid--------------------------------" + openid);
        System.out.println("unionid------------------------------" + unionid);

//跳转到账号绑定页面,并将unionid传给页面
        return new ModelAndView("/portals/account/accountbind", "openid", unionid);
    }
}

WeixinUtil.KAPPSECRET开放平台获取的 appsecret

      3.3 绑定页面及绑定方法

//绑定页面加载,绑定页面需要输入用户名及密码来验证身份

@GetMapping("accountbind")
public String accountBind(Model model, String unionid) {
    model.addAttribute("openid", unionid);
    return "/portals/account/accountbind";
}
//绑定方法

@PostMapping("bind")
@ResponseBody
public Object bind(String username, String password, String unionid) {
    Subject user = SecurityUtils.getSubject();
    UserNameToken token = new UserNameToken(username, password, username);
    token.setRememberMe(false);
    try {

//根据用户输入的用户名密码进行登陆,登陆不成功则验证失败,成功后再进行微信绑定         user.login(token);
        UserVo uservo = new UserVo();
        uservo.setName(username);
        uservo.setP_email(username);
        List<User> listLogin = userService.selectByLoginName(uservo);
        System.out.println("listLogin==" + listLogin);
        Long id = listLogin.get(0).getId();
        String open_id = listLogin.get(0).getOpen_id();

//判断openid是否为空,

//为空则表示没有绑定,将openid插入到当前登陆用户的表中

//不为空则表示已经被绑定过,不可以再次绑定
        if (open_id == "" || open_id == null) {
            userService.bindOpenId(id, unionid);//绑定openid
        } else {
            return renderError("该账号已绑定!");
        }
    } catch (UnknownAccountException e) {
        throw new RuntimeException("账号不存在!", e);
    } catch (DisabledAccountException e) {
        throw new RuntimeException("账号未启用!", e);
    } catch (IncorrectCredentialsException e) {
        throw new RuntimeException("密码错误!", e);
    } catch (Throwable e) {
        throw new RuntimeException(e.getMessage(), e);
    }
    return renderSuccess();
}

参考:https://blog.csdn.net/qq_37361830/article/details/80415947

           https://blog.csdn.net/weixin_41981080/article/details/81869592

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章