开放平台–扫描微信二维码登录

news/2024/11/29 10:47:55/

准备

如不了解第三方登录流程,建议先大概了解一下,在来看看代码。
说明: 由于开放平台无测试号测试,所以只能上开放平台进行配置信息。公众平台的测试号并不能给开放平台使用。

微信开放平台地址:https://open.weixin.qq.com/cgi-bin/index?t=home/index&lang=zh_CN

配置步骤如下:

1、创建web应用
在这里插入图片描述
当创建成功的时候会有appidappsecret,下面代码需要用到。
创建好之后需要设置回调域 ,就是当扫码通过之后会调用该域内的地址,地址在下面代码种配置。

2、注意!!!
1、设置回调域的时候,前面不能加上http://等协议。只需要配置域名即可,如baidu.com,spring.io等。填写成http://spring.io/是错误的
2、域名不能加端口号

代码

<一> 获取二维码

  /*** 跳转至微信登录界面*/// Result 定义的类,返回给前端的信息@ApiOperation(value = "网站-微信扫码登录路径", notes = "网站-微信扫码登录路径")@GetMapping(value = "/web/wxLoginPage")public Result webWxKfLoginPage() throws Exception {String url = WeChatLoginUtil.webWxKfLoginPage();return Result.Builder.newBuilder(AppTipStatusEmum.SUCCESS_STATUS.getCode(), AppTipMsgEnum.SELECT_SUCCESS.getText()).setMessage("获取二维码成功!").setData(url).build();}

涉及的WeChatLoginUtil类如下:

import com.uwa.mall.user.module.enums.ThirdPartyLoginEnum;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;public class WeChatLoginUtil {// ===============================================web方式==================================================// 网页方式登录(scope=snsapi_login)public static String webWxKfLoginPage() throws Exception {// 防止csrf攻击(跨站请求伪造攻击)String state = UUID.randomUUID().toString().replaceAll("-", "");// 存入redis。 CacheUtil为封装redis的工具类CacheUtil.set(ThirdPartyLoginEnum.WeChatEnum.WeChatKFState.getCode() + state, "ok", Integer.valueOf(ThirdPartyLoginEnum.WeChatEnum.WeChatKFStateTime.getCode()));// 普通微信三方地址String url = ThirdPartyLoginEnum.WeChatEnum.AppUrl.getCode() + "appid=" + ThirdPartyLoginEnum.WeChatEnum.AppID.getCode() + "&redirect_uri=" + ThirdPartyLoginEnum.WeChatEnum.RedirectUri.getCode()+ "&response_type=code&scope=snsapi_login&state=" + state + "#wechat_redirect";return url;}/*** 通过code获取token** @return*/public static Map getAccessToken(String code, String appid, String secret) throws Exception {// 构建请求数据Map t = new HashMap();t.put("appid", appid);t.put("secret", secret);t.put("code", code);t.put("grant_type", "authorization_code");// 调用httpclient处理请求得到返回json数据String returnJson = HttpClientUtil.httpGet(ThirdPartyLoginEnum.WeChatEnum.AccessTokenUri.getCode(), t);Map token = JsonUtil.fromJson(returnJson, Map.class);return token;}/*** 刷新token处理** @return*/public static Map refreshToken(String appid, String refresh_token) throws Exception {// 构建请求参数Map m = new HashMap();m.put("appid", appid);m.put("grant_type", "refresh_token");m.put("refresh_token", refresh_token);String s = HttpClientUtil.httpGet(ThirdPartyLoginEnum.WeChatEnum.UrlRefresh.getCode(), m);// 调用httpclient发出请求Map refreshToken = JsonUtil.fromJson(s, Map.class);return refreshToken;}/*** 通过token获取用户信息* * @param token* @return*/public static String getUserInfo(Map token) throws Exception {// 构建请求数据Map u = new HashMap();u.put("access_token", token.get("access_token"));u.put("openid", token.get("openid"));u.put("lang", "zh_CN");// 调用httpclient处理请求得到用户信息json数据String userinfo = HttpClientUtil.httpGet(ThirdPartyLoginEnum.WeChatEnum.UrlUserInfo.getCode(), u);return userinfo;}// ===============================================公众号方式==================================================// 公众号方式登录(scope=snsapi_base)public static String publicWxKfLoginPage() {String state = UUID.randomUUID().toString().replaceAll("-", "");CacheUtil.set(ThirdPartyLoginEnum.PublicWeChatEnum.WeChatKFState.getCode() + state, "ok", Integer.valueOf(ThirdPartyLoginEnum.PublicWeChatEnum.WeChatKFStateTime.getCode()));String url = ThirdPartyLoginEnum.PublicWeChatEnum.AppUrl.getCode() + "appid=" + ThirdPartyLoginEnum.PublicWeChatEnum.AppID.getCode() + "&redirect_uri="+ ThirdPartyLoginEnum.PublicWeChatEnum.RedirectUri.getCode() + "&response_type=code&scope=snsapi_userinfo&state=" + state + "#wechat_redirect";return url;}// 公众号 通过code获取tokenpublic static Map getAccessTokenByPublic(String code, String appid, String secret) throws Exception {// 构建请求数据Map t = new HashMap();t.put("appid", appid);t.put("secret", secret);t.put("code", code);t.put("grant_type", "authorization_code");// 调用httpclient处理请求得到返回json数据String returnJson = HttpClientUtil.httpGet(ThirdPartyLoginEnum.PublicWeChatEnum.AccessTokenUri.getCode(), t);Map token = JsonUtil.fromJson(returnJson, Map.class);return token;}public static Map refreshTokenByPublic(String appid, String refresh_token) throws Exception {// 构建请求参数Map m = new HashMap();m.put("appid", appid);m.put("grant_type", "refresh_token");m.put("refresh_token", refresh_token);String s = HttpClientUtil.httpGet(ThirdPartyLoginEnum.PublicWeChatEnum.UrlRefresh.getCode(), m);// 调用httpclient发出请求Map refreshToken = JsonUtil.fromJson(s, Map.class);return refreshToken;}public static String getUserInfoByPublic(Map token) throws Exception {// 构建请求数据Map u = new HashMap();u.put("access_token", token.get("access_token"));u.put("openid", token.get("openid"));u.put("lang", "zh_CN");// 调用httpclient处理请求得到用户信息json数据String userinfo = HttpClientUtil.httpGet(ThirdPartyLoginEnum.PublicWeChatEnum.UrlUserInfo.getCode(), u);return userinfo;}}

涉及的ThirdPartyLoginEnum枚举接口类如下:

// 第三方登录方式
public interface ThirdPartyLoginEnum {// 网页微信登录方式enum WeChatEnum {AppID("xxx.....xxx","微信开发平台的AppID"),AppSecret("xxx.....xxx","微信开发平台的AppSecret"),AppUrl("https://open.weixin.qq.com/connect/qrconnect?","微信第三方地址"),RedirectUri("http://www.ycj.com/login/wxLogin","登录成功的回调地址"),  //这里的域名和前面配置的域名必须一致,且不能加端口号AccessTokenUri("https://api.weixin.qq.com/sns/oauth2/access_token","获取access_token的地址"),UrlRefresh("https://api.weixin.qq.com/sns/oauth2/refresh_token","刷新获取微信token"),UrlUserInfo("https://api.weixin.qq.com/sns/userinfo","获取用户信息"),WeChatKFState("wechat-kf-state","redis的key"),WeChatKFStateTime("300","redis的key的过期时间(秒)");private String code;private String msg;WeChatEnum(String c, String m) {this.code = c;this.msg = m;}public String getCode() {return code;}public String getMsg() {return msg;}}// 公众号微信登录方式(移动端)enum PublicWeChatEnum {AppID("xxx.....xxx","微信公众平台的AppID"),AppSecret("xxx.....xxx","微信公众平台的AppSecret"),AppUrl("https://open.weixin.qq.com/connect/oauth2/authorize?","微信第三方地址"),RedirectUri("http://activate.navicat.com/mall/user/api/loginAndRegister/public/wxLoginCallback","登录成功的回调地址"),  //这里的域名和公众平台(不是本文的)配置的域名必须一致,且不能加端口号AccessTokenUri("https://api.weixin.qq.com/sns/oauth2/access_token","获取access_token的地址"),UrlRefresh("https://api.weixin.qq.com/sns/oauth2/refresh_token","刷新获取微信token"),UrlUserInfo("https://api.weixin.qq.com/sns/userinfo","获取用户信息"),WeChatKFState("wechat-kf2-state","redis的key"),WeChatKFStateTime("300","redis的key的过期时间(秒)");private String code;private String msg;PublicWeChatEnum(String c, String m) {this.code = c;this.msg = m;}public String getCode() {return code;}public String getMsg() {return msg;}}enum CacheParamEnum{WXOpenID("WX_OpenID_","redis的key"),WXOpenIDTime("300","redis的key的过期时间(秒)");private String code;private String msg;CacheParamEnum(String c, String m) {this.code = c;this.msg = m;}public String getCode() {return code;}public String getMsg() {return msg;}}}

<二>扫码登录回调

  // type有web和public两种类型,本文是开放平台,{type}使用的是web@ApiOperation(value = "微信登录回调", notes = "微信登录回调")@GetMapping("/{type}/wxLoginCallback")public Result wxLoginCallback(@PathVariable("type") String type, @RequestParam(name = "code") String code, @RequestParam(name = "state", required = false) String state) throws Exception {return thirdLoginService.wxLoginCallback(code, state, type);}

涉及的thirdLoginService.wxLoginCallback接口代码如下:

  // 微信登录回调@Override@Transactional(rollbackFor = Exception.class)public Result wxLoginCallback(String code, String state, String type) throws Exception {AssertException.isNull(code, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败:code is empty,请重新登录!");AssertException.isNull(state, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败:state is empty,请重新登录!");Map userMap = null;int regType = RegisterTypeEnum.WX_WEB.getCode();  //枚举:web类型是开放平台,public是公众平台if ("web".equals(type)) {userMap = thirdGetUserInfoService.wxGetUserInfo(code, state);  //获取用户信息} else if ("public".equals(type)) {regType = RegisterTypeEnum.WX_MP.getCode();userMap = thirdGetUserInfoService.wxPublicGetUserInfo(code, state);  //获取用户信息} else {AssertException.assertException(AppTipMsgEnum.LOGIN_FAIL.getCode(), "回调类型错误!");}AssertException.isNullObject(userMap, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败,请重新登录!");AssertException.assertException(userMap.get("errcode") != null, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败:" + userMap.get("errmsg") + ",请重新登录!");AssertException.isNullObject(userMap.get("openid"), AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败:openid为空!,请重新登录!");// 以下是你自己的代码逻辑操作......// 以下是你自己的代码逻辑操作......// 以下是你自己的代码逻辑操作......return Result.Builder.newBuilder(AppTipStatusEmum.SUCCESS_STATUS.getCode(), AppTipMsgEnum.SUCCESS.getText()).setData(objectMap).build();}

涉及的thirdGetUserInfoService类的代码如下:

@Service("thirdGetUserInfoService")
public class ThirdGetUserInfoServiceImpl implements ThirdGetUserInfoService {// 微信web方式获取用户信息@Overridepublic Map wxGetUserInfo(String code, String state) throws Exception {AssertException.isNull(code, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败:code is empty,请重新登录!");AssertException.isNull(state, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败:state is empty,请重新登录!");// 判断state是否合法String stateStr = CacheUtil.get(ThirdPartyLoginEnum.WeChatEnum.WeChatKFState.getCode() + state);AssertException.assertException(StringUtils.isEmpty(code) || StringUtils.isEmpty(state) || StringUtils.isBlank(stateStr), AppTipMsgEnum.PARAM_NOT_NULL.getCode(), "非法操作,请重新登录!");// 用户授权后的code换取tokenMap t_token = WeChatLoginUtil.getAccessToken(code, ThirdPartyLoginEnum.WeChatEnum.AppID.getCode(), ThirdPartyLoginEnum.WeChatEnum.AppSecret.getCode());// 判断是否成功获取到了tokenAssertException.isNullObject(t_token, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败,请重新登录!");AssertException.assertException(t_token.get("errcode") != null, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败:" + t_token.get("errmsg") + ",请重新登录!");AssertException.assertException(StringUtils.isEmpty((String) t_token.get("access_token")) || StringUtils.isEmpty((String) t_token.get("openid")), AppTipMsgEnum.PARAM_NOT_NULL.getCode(),"access_token拉取失败,请重新登录!");// 刷新accesstokenMap refreshToken = WeChatLoginUtil.refreshToken(ThirdPartyLoginEnum.WeChatEnum.AppID.getCode(), (String) t_token.get("refresh_token"));AssertException.isNullObject(refreshToken, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败,请重新登录!");AssertException.assertException(refreshToken.get("errcode") != null, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败:" + refreshToken.get("errmsg") + ",请重新登录!");// 使用token交换获取用户信息String userInfo = WeChatLoginUtil.getUserInfo(refreshToken);return JsonUtil.fromJson(userInfo, Map.class);}// 微信公众号方式获取用户信息@Overridepublic Map wxPublicGetUserInfo(String code, String state) throws Exception {AssertException.isNull(code, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败:code is empty,请重新登录!");AssertException.isNull(state, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败:state is empty,请重新登录!");// 判断state是否合法String stateStr = CacheUtil.get(ThirdPartyLoginEnum.PublicWeChatEnum.WeChatKFState.getCode() + state);AssertException.assertException(StringUtils.isEmpty(code) || StringUtils.isEmpty(state) || StringUtils.isBlank(stateStr), AppTipMsgEnum.PARAM_NOT_NULL.getCode(), "非法操作,请重新登录!");// 用户授权后的code换取tokenMap t_token = WeChatLoginUtil.getAccessTokenByPublic(code, ThirdPartyLoginEnum.PublicWeChatEnum.AppID.getCode(), ThirdPartyLoginEnum.PublicWeChatEnum.AppSecret.getCode());// 判断是否成功获取到了tokenAssertException.isNullObject(t_token, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败,请重新登录!");AssertException.assertException(t_token.get("errcode") != null, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败:" + t_token.get("errmsg") + ",请重新登录!");AssertException.assertException(StringUtils.isEmpty((String) t_token.get("access_token")) || StringUtils.isEmpty((String) t_token.get("openid")), AppTipMsgEnum.PARAM_NOT_NULL.getCode(),"access_token拉取失败,请重新登录!");// 刷新accesstokenMap refreshToken = WeChatLoginUtil.refreshTokenByPublic(ThirdPartyLoginEnum.PublicWeChatEnum.AppID.getCode(), (String) t_token.get("refresh_token"));AssertException.isNullObject(refreshToken, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败,请重新登录!");AssertException.assertException(refreshToken.get("errcode") != null, AppTipMsgEnum.LOGIN_FAIL.getCode(), "登录失败:" + refreshToken.get("errmsg") + ",请重新登录!");// 使用token交换获取用户信息String userInfo = WeChatLoginUtil.getUserInfoByPublic(refreshToken);return JsonUtil.fromJson(userInfo, Map.class);}
}

至此代码就算完成了,不足之处欢迎指教
由于框架用不明白,不想去理解,感觉配置太麻烦了,花那个时间去研究框架,我都写完了。

公众平台的登录请看另一篇:公众平台–扫描微信二维码,关注后自动登录


http://www.ppmy.cn/news/653810.html

相关文章

微信扫描二维码登录第三方平台

嗯。。。。。。 最近做了一个微信扫码登陆第三方平台功能&#xff0c;说下步骤就行&#xff0c;反正原理你们网上直接百度&#xff0c;我这里写了&#xff0c;估计也没几个人有耐心看 第一步 生成一个链接 https://open.weixin.qq.com/connect/qrconnect?appidxxxxxxxxf&…

keil_arm满减栈应用场景

.text .global _start _start:满减压栈使用场景ldr sp,0x40000800mov r0,#0x1mov r1,#0x2bl add1_funcadd r0,r0,r1 r0 r0 r1 0x3b stopadd1_func: 压栈保存现场 r0 0x1 r1 0x2stmfd sp!,{r0,r1&#xff0c;lr}mov r0,#0x3mov r1,#0x4bl add2_funcadd r0,r0,r1 r0 r…

小程序中使用scroll-view组件,内容高度未超过容器高度时依然可以上下滑动小段距离的问题

解决办法&#xff1a; 如下代码&#xff1a;检查下scroll-view组件是否设置了上下padding 或者 scroll-view的父盒子< view class“home-page” >…< /view >设置了上下padding&#xff0c;如果设置了&#xff0c;去掉就可以解决问题。 <view class"home…

word设置页眉页码 首页没有页眉(终于搞懂了)

1.设置首页没有页眉 主要是通过分节符完成的&#xff0c;顾名思义&#xff0c;分节符就是将全文分为两节&#xff0c;然后就可以实现对两节内容的分别设置。 比如首页没有页眉。 在首页的最后一行插入分节符&#xff0c;然后就会显示出&#xff08;分节符&#xff08;下一页…

去掉WORD文档中首页的页眉及页眉的横线

去掉WORD文档中首页的页眉及页眉的横线 左直拳 用WORD写文档&#xff0c;少不得加上页眉页脚。 可是有时候&#xff0c;写一个长一点的文档&#xff0c;需要制作一个封面&#xff0c;比如&#xff0c;写上“叉叉叉管理系统&#xff0c;某某某单位”之类&#xff0c;却猛然发现&…

python-docx修改页眉页脚

官方文档肯定是最正规的&#xff0c;但是有点简单&#xff0c;有必要记一下&#xff0c;网上资料较少。 https://python-docx.readthedocs.io/en/latest/dev/analysis/features/header.html?highlightfooter 打开一个文档后&#xff0c;页眉和页脚是跟着“节”走的&#xff…

word页眉页脚修改

一、要求&#xff1a;一个word文档里有多个封面、目录和正文内容。 1、要求页眉奇数页为“作者&#xff1a;毕设题目”&#xff0c;偶数页为“本科毕业设计”&#xff1b; 2、页脚奇数页“向右对齐”&#xff0c;偶数页向左对齐&#xff1b; 3、封面和目录不能有页眉页脚。 …

奥斯汀页眉怎么设置_Word页眉横线怎么去掉与页眉页脚如何设置删除,含首页、奇数偶数页、横纵向页不同及第一页与最后一页不要页...

在 Word 中,页眉页脚默认情况下所有页都一样,但可以设置首页不同、奇偶页不同、纵向页与横向页不同,还可以设置第一页 与最后一页不要页眉但中间的所有页都要页眉。设置奇偶页不同后,还可以设置奇偶页页码连续。 默认情况下,页眉页脚有横线(即文字下有下划线),如果不想要…