微信公众号授权登录,整合spring security
公司的业务需求,对接了微信公众号授权,通过微信公众号的接口拿到用户信息进行业务系统的登录,话不多说上代码,我的实现方式是整合了spingSecurity
首先是接口
@PostMapping("/official/login")
@ApiOperation(value = "公众号授权登录", notes = "此接口返回系统的token")
public AjaxResult officialLogin(@RequestBody String code){
AjaxResult ajax = AjaxResult.success();
String token = mobileLoginService.officialLogin(code);
ajax.put(Constants.TOKEN, token);
return ajax;
}
然后是service
/**
* 公众号登录
* @param code 授权码
* @return token
*/
public String officialLogin(String code) {
// 用户验证
Authentication authentication = null;
try {
MobileUserByOfficialAuthenticationToken officialAuthenticationToken =
new MobileUserByOfficialAuthenticationToken(code);
AuthenticationContextHolder.setContext(officialAuthenticationToken);
// 该方法会去调用MobileUserByOfficialDetailsServiceImpl.loadUserByUsername
authentication = authenticationManager.authenticate(officialAuthenticationToken);
} catch (Exception e) {
if (e instanceof BadCredentialsException) {
throw new UserPasswordNotMatchException();
} else {
throw new ServiceException(e.getMessage());
}
} finally {
AuthenticationContextHolder.clearContext();
}
MobileLoginUser mobileLoginUser = (MobileLoginUser) authentication.getPrincipal();
recordLoginInfo(mobileLoginUser.getUserId());
return tokenService.createToken(mobileLoginUser);
}
这里开始涉及到spring security,自定义一个MobileUserByOfficialAuthenticationToken ,用于authenticationManager找到合适的authenticationProvider来处理请求
/**
* @Description : 移动用户-公众号登录
* @Author : wzkris
* @Version : V1.0.0
* @Date : 2022/12/14 17:30
*/
public class MobileUserByOfficialAuthenticationToken extends AbstractAuthenticationToken { private final String code; /**
* Creates a token with the supplied array of authorities.
*/
public MobileUserByOfficialAuthenticationToken(String code) {
super(null);
this.code = code;
} /**
* @return 公众号授权需要的code
*/
public String getCode() {
return code;
} @Override
public Object getCredentials() {
return null;
} @Override
public Object getPrincipal() {
return null;
}
}
/**
* @Description : 公众号登录验证器
* @Author : wzkris
* @Version : V1.0.0
* @Date : 2022/12/14 17:33
*/
@Component
public class MobileUserByOfficialAuthenticationProvider implements AuthenticationProvider { @Resource(name = "mobileUserByOfficialDetailsServiceImpl")
private UserDetailsService userDetailsService; @Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
MobileUserByOfficialAuthenticationToken authenticationToken = (MobileUserByOfficialAuthenticationToken) authentication;
UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationToken.getCode());
//微信授权登录,无密码
return new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
} @Override
public boolean supports(Class<?> authentication) {
return MobileUserByOfficialAuthenticationToken.class.equals(authentication);
}
}
下面的是具体请求微信拿到openId的方法
/**
* @Description : 微信公众号登录服务
* @Author : wzkris
* @Version : V1.0.0
* @Date : 2022/12/14 17:35
*/
@Service
public class MobileUserByOfficialDetailsServiceImpl implements UserDetailsService { @Resource
private RestTemplate restTemplate; @Resource
private MobileUserWechatService mobileUserWechatService; @Resource
private MobileUserService mobileUserService; @Resource
private ISysConfigService configService; @Resource
private WxOfficialService wxOfficialService; @Resource
private TransactionTemplate transactionTemplate; @Override
public UserDetails loadUserByUsername(String code) throws UsernameNotFoundException {
//获取请求token
OfficialAccessResult loginAccessToken = wxOfficialService.getLoginAccessToken(code);
//构造请求
String url = "https://api.weixin.qq.com/sns/userinfo" +
"?access_token=" + loginAccessToken.getAccessToken()
+ "&openid=" + loginAccessToken.getOpenId()
+ "&lang=zh_CN";
ResponseEntity<OfficialLoginResult> response = restTemplate.getForEntity(URI.create(url), OfficialLoginResult.class);
OfficialLoginResult loginResult = response.getBody();
//校验返回结果
Objects.requireNonNull(loginResult);
WxErrCodeUtils.checkResult(loginResult);
//业务逻辑
MobileUserWechat userWechat = mobileUserWechatService.queryByOpenId(loginResult.getOpenId());
//不为空则代表已经注册过,直接查询出来返回
if (ObjectUtils.isNotEmpty(userWechat)) {
MobileUser user = mobileUserService.getById(userWechat.getUserId());
return createLoginUser(user);
}
//否则就代表第一次登录,直接插入并且注册
String password = configService.selectConfigByKey("sys.user.initPassword"); MobileUser user = new MobileUser()
.setPassword(SecurityUtils.encryptPassword(password))
.setUsername(IdUtils.fastSimpleUUID())
.setNickname(loginResult.getNickname())
.setAvatar(loginResult.getHeadImgUrl())
.setSex(exchangeSex(loginResult.getSex()))
.setPhone(Constants.UNKNOWN);
//开启事务,保存用户和微信信息
transactionTemplate.execute(status -> {
mobileUserService.save(user);
mobileUserWechatService.save(new MobileUserWechat()
.setOpenId(loginAccessToken.getOpenId())
.setUnionId(loginAccessToken.getUnionId())
.setChannel(Constants.CHANNEL_OFFICIAL)
.setUserId(user.getId()));
return null;
});
return createLoginUser(user);
} private UserDetails createLoginUser(MobileUser user) {
return new MobileLoginUser(user, Constants.CHANNEL_OFFICIAL);
} /**
* @param sex 性别
* @return 微信性别转换成系统的性别
*/
private int exchangeSex(int sex) {
int real = sex - 1;
if (real < 0) {
return 2;
}
return real;
} }
微信公众号授权登录,整合spring security的更多相关文章
- 【tp5.1】微信公众号授权登录及获取信息录入数据库
微信公众号开发文档链接:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432 微信公众号授权登录分为两种: 1.以 ...
- 解决微信公众号授权登录和开放平台微信第三方应用授权登录获取到的用户Openid关联问题
开发背景: 最近一段时间一直在做关于微信方面的网站应用开发,这段时间也收获的不少关于微信开发方面的开发技能,接触的比较多的主要有微信公众号和微信网站app第三方登录授权,以及微信会员卡,优惠券和扫描二 ...
- uniapp - 微信公众号授权登录
[缘由] 采用uniapp进行微信小程序和微信公众号双版本开发:考虑到用户唯一性,我们后端确定了以“unionid”.作为唯一标识. 有的小伙伴估计也是刚入这坑,我就简单说一下步骤流程 [摸索] ...
- 微信公众号授权登录,提示“redirect_uri 参数错误”
做微信公众号开发授权登录的时候遇到的坑... 后台服务用node,index.js相关代码如下: const oauth = new OAuth(conf.appid, conf.appsecret) ...
- 微信公众号授权登录后报redirect_uri参数错误的问题
在进行微信公众号二次开发的时候,需要通过授权码模式来进行微信授权.比如,在进行登录的时候,用户点击了登录按钮,然后弹出一个授权框,用户点击同意后,就可以获取用户的OpenId等信息了.这篇文章主要 ...
- Chrome插件:微信公众号自动登录(chrome.extension)
manifest.json: { "manifest_version": 2, "name": "WX.AutoLogin", " ...
- 微信公众号授权,支付,退款总结【shoucang】
1.支付前准备 1.1首先两个平台接入账户. 商户平台:https://pay.weixin.qq.com/index.php/core/home/login?return_url=%2F 公众平台: ...
- PHP之路——微信公众号授权获取用户信息
官方文档链接:http://mp.weixin.qq.com/wiki/4/9ac2e7b1f1d22e9e57260f6553822520.html /** * 获取code */ public f ...
- 微信公众号授权回调用户信息,获取openid
1.--------------------用户授权登录并获取code 授权登录方式有两个,一种为静默授权登录(scope=snsapi_base),一种为非静默授权登录(scope=snsapi_u ...
- ASP.NET之MVC 微信公众号授权给第三方平台的技术实现流程(获取第三方平台access_token)
“出于安全考虑,在第三方平台创建审核通过后,微信服务器每隔10分钟会向第三方的消息接收地址推送一次component_verify_ticket,用于获取第三方平台接口调用凭据”.这是文档中的原话,也 ...
随机推荐
- 原因代码: 0x2000c 关机类型: 关机
进程 C:\Windows\system32\silsvc.exe (XTKFSERVER2019) 由于以下原因已代表用户 NT AUTHORITY\SYSTEM 启动计算机 XTKFSERVER2 ...
- 解决idea不能自动下载maven配置文件pom.xml下的jar包依赖的问题
表现:无法下载pom配置文件中的依赖包,或只能下载少数包,各项配置都正确的情况 理由未知: 百度了很长一段时间,网上给出比较精准的解决之一是 setting>>maven>>去 ...
- docker 安装后报错处理
问题场景: Docker服务安装之后启动报错 日志如下: time="2022-03-20T21:51:16.116163560+08:00" level=info msg=&qu ...
- 那些年vue踩过的坑v-if渲染完dom重新渲染 获取dom问题
当查询完成是 加载chart图了, 因为 上面的 div 是v-if 还没来得级渲染 所以获取下面chart div 时 没有dom元素 报错了
- 【Java】zuul
报错 com.netflix.zuul.exception.ZuulException: Hystrix Readed time out 解决办法,zuul模块的yml配置文件增加 ribbon: C ...
- PostScript语言教程(四、程序变量使用)
4.1.变量定义 POSTSCRIPT 变量 变量的定义是将比那两名和值用def进行关联类似 /ppi 75 def %将ppi定义为75 /ppi ppi 1 add def %将ppi + 1的值 ...
- Ant Design 分页数据回显问题
我们可以创建一个新的值来保存这些数据allSingleSelectedRowKeys: 下面是我们的HTML结构 <a-table :row-selection="{ selected ...
- 大唐电信AC集中管理平台弱口令漏洞
网络资产搜索: 找到平台 进行默认口令登入:admin/1***** 登陆 End!!!
- ZSTUOJ刷题⑩:Problem B.--零起点学算法103——查找最大元素
Problem B: 零起点学算法103--查找最大元素 Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 9951 Solved: 4793 Descri ...
- Dapper修改
<table class="table table-bordered"> <tr> <td>商品名称:</td> <td> ...