feat: 微信登录功能开发

This commit is contained in:
wangtaocs
2024-11-29 11:09:56 +08:00
parent d2f240776e
commit d24dafc1fb
14 changed files with 164 additions and 2 deletions

View File

@@ -61,4 +61,14 @@ public class AuthController {
AuthTokenResponse authTokenResponse = authService.refreshToken(request);
return Result.success(authTokenResponse);
}
@Operation(summary = "微信登录")
@PostMapping("/wechatLogin")
@Log(value = "微信登录", module = LogModuleEnum.LOGIN)
public Result<AuthTokenResponse> wechatLogin(
@Parameter(description = "微信授权码", example = "code") @RequestParam String code
) {
AuthTokenResponse loginResult = authService.wechatLogin(code);
return Result.success(loginResult);
}
}

View File

@@ -40,4 +40,11 @@ public interface AuthService {
* @return 登录结果
*/
AuthTokenResponse refreshToken(RefreshTokenRequest request);
/**
* 微信登录
* @param code 微信登录code
* @return 登录结果
*/
AuthTokenResponse wechatLogin(String code);
}

View File

@@ -1,11 +1,14 @@
package com.youlai.boot.shared.auth.service.impl;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.hutool.captcha.AbstractCaptcha;
import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.generator.CodeGenerator;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.youlai.boot.common.constant.SecurityConstants;
import com.youlai.boot.common.constant.SystemConstants;
import com.youlai.boot.common.exception.BusinessException;
import com.youlai.boot.common.result.ResultCode;
import com.youlai.boot.core.security.util.SecurityUtils;
@@ -16,8 +19,12 @@ import com.youlai.boot.shared.auth.model.CaptchaResponse;
import com.youlai.boot.shared.auth.model.AuthTokenResponse;
import com.youlai.boot.config.property.CaptchaProperties;
import com.youlai.boot.shared.auth.service.TokenService;
import com.youlai.boot.system.model.entity.User;
import com.youlai.boot.system.model.form.UserForm;
import com.youlai.boot.system.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@@ -26,6 +33,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import java.awt.*;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
@@ -45,6 +53,8 @@ public class AuthServiceImpl implements AuthService {
private final Font captchaFont;
private final CaptchaProperties captchaProperties;
private final TokenService tokenService;
private final WxMaService wxMaService;
private final UserService userService;
/**
* 登录
@@ -148,4 +158,51 @@ public class AuthServiceImpl implements AuthService {
return tokenService.refreshToken(refreshToken);
}
@Override
public AuthTokenResponse wechatLogin(String code) {
// 1. 通过code获取微信access_token
WxMaJscode2SessionResult sessionInfo = null;
try {
sessionInfo = wxMaService.getUserService().getSessionInfo(code);
} catch (WxErrorException e) {
log.error("微信小程序登录失败", e);
throw new BusinessException(e);
}
String openId = sessionInfo.getOpenid();
if (StrUtil.isBlank(openId)) {
throw new BusinessException("微信授权失败");
}
// todo 获取微信用户信息
// WxMaUserInfo userInfo = wxMaService.getUserService().getUserInfo(sessionInfo.getSessionKey(), sessionInfo.getOpenid());
// 2. 根据openId查询用户信息如果不存在则注册新用户
User user = userService.getUserByOpenId(openId);
if (Objects.isNull(user)) {
String name = "微信用户" + IdUtil.simpleUUID();
UserForm newUser = new UserForm();
newUser.setOpenId(openId);
newUser.setNickname(name);
newUser.setUsername(name);
boolean result = userService.saveUser(newUser);
if (!result) {
throw new BusinessException("微信用户注册失败");
}
}
user = userService.getUserByOpenId(openId);
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(user.getUsername().toLowerCase().trim(), SystemConstants.DEFAULT_PASSWORD);
// 执行用户认证
Authentication authentication = authenticationManager.authenticate(authenticationToken);
// 认证成功后生成JWT令牌
AuthTokenResponse authTokenResponse = tokenService.generateToken(authentication);
// 将认证信息存入Security上下文便于在AOP如日志记录中获取当前用户信息
SecurityContextHolder.getContext().setAuthentication(authentication);
// 返回包含JWT令牌的登录结果
return authTokenResponse;
}
}