微信掃碼登陸過程
- 在微信開放平臺上註冊並創建網站應用,等待審覈;需提供公司章及域名等信息
- 審覈通過後獲取AppID和AppSecret
- 思考流程:
- 首先思考如何生成二維碼
- 掃碼後的情況
- 用戶未綁定網站時,跳轉到綁定界面
- 用戶綁定過網站,掃碼後直接登陸並跳轉到首頁
- 用戶綁定賬號的問題:
- 該賬號已綁定過,需要提示
- 該微信已綁定過(不需要想了,掃碼直接登陸了,不會跳轉到綁定界面)
- 用戶解綁:
- 在個人中心添加對微信綁定的管理,解綁就是將微信獲取到的unionid置空即可。
- 編碼思路:
注意:開放平臺只有綁定公衆號纔可以獲取到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