主要流程:
微信授权登录让微信用户使用微信身份安全登录第三方应用或网站,在微信用户授权登录已接入微信的第三方应用后,第三方可以获取到用户的接口调用凭证(access_token),通过access_token可以进行微信开放平台授权关系接口调用,从而可实现获取微信用户基本开放信息和帮助用户实现基础开放功能等。该模式整体流程为:
(1) 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;
(2)通过code参数加上AppID和AppSecret等,通过API换取access_token;
(3)通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。
1.在登录页准备微信登录的按钮
2.当用户点击微信登录时,页面向微信发起获取授权的请求
//微信登录
wechatLogin () {let redirectUri = encodeURI(location.href)//对当前页的URL进行转码if (this.isWinxin) {//判断如果是微信浏览器,授权登录,否则扫码登录wxAuthLogin(redirectUri)} else {let _appid = 'wxxxxxxxx'var wxLogin = new WxLogin({self_redirect: false,id: 'wx_box', //需要承载二维码的容器id appid: _appid,scope: 'snsapi_login', //网页授权,目前网页只有这一种方式,静默授权redirect_uri: redirectUri, //回调域名state: 'open',style: 'white',href: ''})}
},// 微信授权登录
export function wxAuthLogin (redirectUri) {window.open('https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxxxxxxx&redirect_uri=' + redirectUri + '&response_type=code&scope=snsapi_userinfo&state=public#wechat_redirect')
}
3.微信直接展示扫描二维码给用户(询问用户要不要给我们项目授权)
4.用户扫码,确认授权页面可以获取微信用户信息
授权原理:
(1)用户通过手机微信确认登录之后,微信方会返回一个授权码code给回第三方(接入方),这个授权码code一次有效,且有效时间比较短;
(2)第三方通过此code去调用微信接口获取token,token的有效期也比较短,当然用户可以通过刷新token的方式来延长token的有效时长;
(3)第三步,通过token再去调用微信开发平台接口,获取微信个人用户信息。
微信浏览器直接登录和pc端微信扫码登录,两者的授权流程一样,需要授权获取code换取token和openid再去请求用户信息。
5.微信收到确认,生成code(授权码),通过回调域拼接code返回
https://www.xxx.pro/login?redirect=%2Farticle&code=041W1vll2qzrP74gdbml2FRLdY0W1vll&state=open
6.页面上获取授权码之后,从url中获取code,并且触发调用后端的微信登录接口,将code传送到后端
beforeRouteEnter (to, from, next) {next(vm => {let _url = getUrlSearch()if (_url && _url.code) {getUserByCodeApi({code: _url.code}).then(res => {if (res.data.success) {vm.setUser()vm.$message.success(res.data.operateMessage)vm.$router.push(decodeURIComponent(_url.state) || '/')} else {vm.$message.error(res.data.operateMessage)}})}})
}
7.后端接口收到请求,交给service处理
//通过code获取微信用户信息
WxUserInfoVO wxUserInfo = wxService.getUserInfo(origin, code, encryptedData, iv);
8.请求微信接口拿用户信息,利用code获取access_token 和 openId,用access_token 和openid获取用户信息
/**
* 一,微信用户授权,根据授权code获取用户token
*/
public WxUserTokenVO getUserToken(String appId, String appSecret, String code) throws EmcsCustomException {WxUserTokenVO userTokenVO = wechatApi.getUserToken(appId, appSecret, code);return userTokenVO;
}/**
* 二,根据用户token获取微信用户信息
*/
public WxUserInfoVO getUserInfo(IWxConfig config, String code) throws EmcsCustomException {WxUserTokenVO token = getUserToken(config.getAppID(), config.getAppSecret(), code);WxUserInfoVO userInfoVO = wechatApi.getUserInfo(token.getAccess_token(), token.getOpenid());return userInfoVO;
}
9.判断该用户是已经存在的用户还是首次登录的用户
在不同的公众账号下openid是不一样的,而他们的unionid却是一样的。同一用户,对同一个微信开放平台帐号下的不同应用,UnionID是相同的。
User user = userService.getUserByWxUnionId(wxUserInfo.getUnionid());//根据该用户的UnionID,获取用户信息
if (user != null) {//不为空说明是老用户,如果用户没有登录过当前应用,先获取之前的openid,并将当前应用的openid设为和之前一样if (origin.equals(IWxConfig.ORIGIN_MINIAPP) &&!StringUtils.equals(user.getWxMiniappOpenid(), wxUserInfo.getOpenid())) {user.setWxMiniappOpenid(wxUserInfo.getOpenid());userService.update(user);}if (origin.equals(IWxConfig.ORIGIN_PUBLIC) &&!StringUtils.equals(user.getWxPublicOpenid(), wxUserInfo.getOpenid())) {user.setWxPublicOpenid(wxUserInfo.getOpenid());userService.update(user);}TokenAuthenticationService.addAuthentication(res, user);info = OperationInfo.success("登录成功");info.setOperateCode("200");} else {//说明是新用户,把微信给的id存进数据库,然后用户信息已校验成功的数据录到服务器里User wxUser = new User();if (origin.equals(IWxConfig.ORIGIN_MINIAPP)) {wxUser.setWxMiniappOpenid(wxUserInfo.getOpenid());}}