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

 

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