编程知识 cdmana.com

网站实现微信扫码登录+Java+Shiro 框架

                    网站实现微信扫码登录+Java+Shiro 框架

 

一、准备工作

1、注册微信开放平台:https://open.weixin.qq.com/

2、创建网站应用 , 设置授权回调域。

3、开发者认证 (需要企业资质,费用300元)

 

 

 

二、具体实现步骤

1、网页页面生成二维码 ---- 使用第二种方式

步骤1:在页面中先引入如下JS文件(支持https):
http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js

步骤2:在需要使用微信登录的地方实例以下JS对象:
 var obj = new WxLogin({
     self_redirect:true,
     id:"login_container", 
     appid: "", 
     scope: "", 
     redirect_uri: "",
     state: "",
     style: "",
     href: ""
 });

2、通过code获取access_token(服务端实现)

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

3、第三步:获取用户个人信息(UnionID机制) (服务端实现)

https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID

4、获取到 unionID , 到 sys_user 用户表进行查找用户是否存在

5、用户存在,直接登录

6、用户不存在,进入到提示注册页面

7、使用步骤1生成二维码时,可先从服务端返回对应的参数

@RequestMapping(value = "/pre")
	@ResponseBody
	public Map<String,String> pre(HttpServletRequest request){
		Map<String,String> map = new HashMap<String, String>();
		map.put("AppId", Global.getConfig("weixin.open.AppId"));
		map.put("redirect_url", Global.getConfig("weixin.open.redirect_url"));
		map.put("state", IdGen.uuid().toUpperCase());
		String key =map.get("state");
		WechatCacheUtils.put(key, key);
		return map;
	}

8、伪代码逻辑如下:

@SuppressWarnings("unchecked")
	@RequestMapping(value = "/login")
	public Object login(String code ,String state , Model model , HttpServletRequest request) throws IOException {
		if(StringUtils.isBlank(code) || StringUtils.isBlank(state)) {
			model.addAttribute("message","state or code 参数错误!");
			return "error/invalid";
		}
		logger.debug("code , {}" , code);
		logger.debug("state , {}" , state);
		String key =state;
		Object attribute = WechatCacheUtils.get(key);
		// 1、state 参数校验
		if(null == attribute || !state.equals(attribute.toString())) {
			model.addAttribute("message","非法请求!");
			return "error/invalid";
		}
		WechatCacheUtils.remove(key);
		
		// 2、获取AccessToken
		String openAccessToken = WechatCacheUtils.getOpenAccessToken(code);
		logger.debug("openAccessToken , {}" , openAccessToken);
		Map<String,String> resMap = (Map<String,String>)JsonMapper.fromJsonString(openAccessToken, Map.class);
		// 3、获取用户个人信息 
		String url = WechatConstant.WEIXIN_OPEN_USERINFO.concat("access_token=").concat(resMap.get("access_token"))
														.concat("&openid=").concat(resMap.get("openid"));
		logger.debug("获取用户个人信息url, {}" , url);
		Map<String,String> res = new HashMap<String, String>();
		String doGet = null ;
		try {
			doGet = HttpClientUtils.doGet(url);
			logger.debug("获取用户个人信息,如下: {}" , doGet);
			res = (Map<String,String>)JsonMapper.fromJsonString(doGet, Map.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
		if(StringUtils.isBlank(res.get("unionid"))) {
			// 接口调用失败,无法获取到 unionid
			logger.error("获取用户信息失败, 用户信息接口返回数据如下: {}" , doGet);
			model.addAttribute("message","微信接口错误,请重试!");
			return "error/invalid";
		}
		User temp = new User();
		temp.setWechatUid(res.get("unionid"));
		temp.setNumber(1);
		// 4、根据用户唯一标识,判断是否存在 wechatUid
		List<User> findList = systemService.existsUserByCondition(temp);
		if(CollectionUtils.isEmpty(findList)) {
			// 不存在,跳转到提示到小程序注册页面
			return "modules/sys/guideWechat";
		}
		// 存在,调用shiro 进行登录 
	    Subject subject = SecurityUtils.getSubject();
	    UsernamePasswordToken passwordToken = new UsernamePasswordToken();
	    passwordToken.setUsername(findList.get(0).getLoginName());
	    passwordToken.setPassword(findList.get(0).getPassword().toCharArray());
	    passwordToken.setUnpass(true); // 免密码登录验证
	    subject.login(passwordToken);
	    // 登录成功,跳转到登录管理页面
	    return "redirect:"+adminPath+"/login";
	}

 

三、总结

1、创建网站应用步骤 --- 授权回调域 , 可以随便修改,且及时生效的

 

2、本地调试办法,使用内网穿透,映射一个本地地址即可。参考: Java 微信支付通知本地调试解决办法

3、扫码登录后,若网站使用shiro作为登录管理,建议参考: Shiro实现免密码登录

4、调试的时候,可以使用第一种方法生成二维码,无需校验state

https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect 

 

 

若不明白,欢迎留言沟通,谢谢~

 

 

参考资料: Java后端调用其他服务接口

            Shiro 实现免密码登录策略

 

 

版权声明
本文为[HaHa_Sir]所创,转载请带上原文链接,感谢
https://thinkcode.blog.csdn.net/article/details/110927389

Scroll to Top