微信扫码登录实现
Posted Mr.Tomcat
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信扫码登录实现相关的知识,希望对你有一定的参考价值。
需求
使用微信扫码登录的授权方式登录系统
实现
此扫码登陆过程中使用了,微信开放平台(需支付300开通开发者认证)的网站应用实现的。
官方文档:https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html
流程:
大概就是:前端调接口获取后端生成的state(可以用验证登录授权的有效性)——>用户扫码后确认授权——>前端开始调用微信开放平台的接口之后回调服务端接口——>回调时传入了两个参数,code和state——>根据code,appid和appSecret调用接口获取access_token——根据access_token获取微信用户的个人信息
代码:
前端vue:
安装一个插件:
npm install vue-wxlogin --save-dev
引入组件:
<wxlogin
appid="xxxxxx"
:scope="'snsapi_login'"
theme="black"
redirect_uri="redirectUrl"
:state="xxxxxx"
:self_redirect="'true'"
rel="external nofollow"
/>
注:重定向地址需要使用urlEncode对链接进行处理
后端SpringBoot:
后端生成state接口
@ApiOperation(value = "企业端:获取扫码登录的state", notes = " \\n author:ZhuGuangLiang")
@AnonymousGetMapping("/wx/qrcode")
public Result<Object> getQrCode() throws IOException
//生成票据
String state= IdUtil.simpleUUID();
//可以将state参数作为存放在redis中的授权用户信息key键
redisUtils.set(state, JSON.toJSON(new CompanyWxDTO()), 5 * 60);
return Result.success(state);
回调接口,并携带state和code参数
注:回调接口,尽量不要抛出异常,异常可以在登录接口抛出
@ApiOperation(value = "企业端:微信用户授权后,回调地址", notes = " \\n author:ZhuGuangLiang")
@AnonymousGetMapping("/wx/callback")
public void callback(String code, String state)
companyAuthService.callback(code, state);
//方法中所有第三方接口都可在官方文档中找到
@Override
public void callback(String code, String state)
//authurl获取access_token的接口,可以看官方文档中的第二步
JSONObject resultAuthUrl = JSONObject.parseObject(HttpUtil.get(String.format(authUrl, appid, secret, code)));
boolean isSuccess = true;
if (resultAuthUrl.containsKey("errcode"))
log.error("授权失败");
isSuccess = false;
// throw new BadRequestException(ResultEnum.USER_NO_AUTH);
String openid = resultAuthUrl.getString("openid");
String accessToken = resultAuthUrl.getString("access_token");
String refreshToken = resultAuthUrl.getString("refresh_token");
//根据code获取access_toke
LambdaQueryWrapper<SpiritCompanyUser> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SpiritCompanyUser::getOpenid, openid);
CompanyWxDTO companyWxDTO = loginUtils.noExceptinCheckCompanyUser(queryWrapper);
int type = companyWxDTO.getType();
if (!isSuccess)
//登录失败,此时我使用type类型去记录每一种异常
companyWxDTO.setType(7);
if (type == 1 && isSuccess)
//校验授权凭证
JSONObject resultCheckToken = JSONObject.parseObject(HttpUtil.get(String.format(checkTokenUrl, accessToken, openid)));
if (resultCheckToken.getInteger("errcode") == 40003)
//刷新token,防止出现token失效
JSONObject resultRefreshToken = JSONObject.parseObject(HttpUtil.get(String.format(refreshTokenUrl, appid, refreshToken)));
accessToken = resultRefreshToken.getString("access_token");
//获取用户信息
JSONObject resultUserInfoUrl = JSONObject.parseObject(HttpUtil.get(String.format(userInfoUrl, accessToken, openid)));
log.info("resultUserInfoUrl:" + resultUserInfoUrl.toString());
if (resultUserInfoUrl.containsKey("errcode"))
log.error("获取用户信息失败");
//同上
companyWxDTO.setType(8);
companyWxDTO.setAvatarUrl(resultUserInfoUrl.getString("headimgurl"));
companyWxDTO.setNickName(resultUserInfoUrl.getString("nickname"));
companyWxDTO.setOpenid(openid);
companyWxDTO.setUnionid(resultUserInfoUrl.getString("unionid"));
log.info("微信用户授权成功");
companyWxDTO.setTicket(state);
redisUtils.set(state, JSON.toJSON(companyWxDTO), 5 * 60);
以上是关于微信扫码登录实现的主要内容,如果未能解决你的问题,请参考以下文章