This commit is contained in:
有来技术 2021-09-29 23:55:27 +08:00
parent c93750d73c
commit 54747673ab
20 changed files with 152 additions and 232 deletions

View File

@ -1,14 +1,13 @@
package com.youlai.mall.ums.pojo.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class MemberAuthDTO {
private Long id;
private String username;
private Long userId;
private String openId;
private Integer status;
private String avatar;
private String nickname;
}

View File

@ -65,13 +65,14 @@ public class MemberController {
@ApiImplicitParam(name = "openid", value = "微信身份唯一标识", required = true, paramType = "path", dataType = "String")
@GetMapping("/openid/{openid}")
public Result<MemberAuthDTO> getByOpenid(@PathVariable String openid) {
UmsMember member = iUmsMemberService.getOne(new LambdaQueryWrapper<UmsMember>().eq(UmsMember::getOpenid, openid));
UmsMember member = iUmsMemberService.getOne(new LambdaQueryWrapper<UmsMember>().eq(UmsMember::getOpenid, openid)
.select(UmsMember::getId,UmsMember::getOpenid,UmsMember::getStatus)
);
if (member == null) {
return Result.failed(ResultCode.USER_NOT_EXIST);
}
// 会员认证信息
MemberAuthDTO memberAuth = new MemberAuthDTO();
BeanUtil.copyProperties(member, memberAuth);
MemberAuthDTO memberAuth = new MemberAuthDTO(member.getId(),member.getOpenid(),member.getStatus());
return Result.success(memberAuth);
}

View File

@ -21,7 +21,7 @@ import java.util.List;
import java.util.stream.Collectors;
/**
*用户业务类
* 用户业务类
*/
@Service
@RequiredArgsConstructor
@ -107,7 +107,8 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
@Override
public UserAuthDTO getByUsername(String username) {
return this.baseMapper.getByUsername(username);
UserAuthDTO userAuthInfo = this.baseMapper.getByUsername(username);
return userAuthInfo;
}
}

View File

@ -31,8 +31,19 @@
email,gmt_create,gmt_modified,
deleted
</sql>
<select id="getByUsername" resultMap="BaseResultMap">
select t1.id, t1.username, t1.nickname, t1.password, t1.status, t3.code roleCode
<resultMap id="UserAuthMap" type="com.youlai.admin.pojo.dto.UserAuthDTO">
<id property="userId" column="id" jdbcType="BIGINT"/>
<result property="username" column="username" jdbcType="VARCHAR"/>
<result property="password" column="password" jdbcType="VARCHAR"/>
<result property="status" column="status" jdbcType="BOOLEAN"/>
<collection property="roles" ofType="string" javaType="list">
<result column="roleCode"></result>
</collection>
</resultMap>
<select id="getByUsername" resultMap="UserAuthMap">
select t1.id userId, t1.username, t1.nickname, t1.password, t1.status, t3.code roleCode
from sys_user t1,
sys_user_role t2,
sys_role t3

View File

@ -113,5 +113,4 @@
</plugin>
</plugins>
</build>
</project>

View File

@ -12,6 +12,8 @@ import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableDiscoveryClient
public class AuthApplication {
public static void main(String[] args) {
SpringApplication.run(AuthApplication.class, args);
}
}

View File

@ -5,9 +5,6 @@ import cn.hutool.json.JSONUtil;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.RSAKey;
import com.youlai.auth.common.enums.OAuthClientEnum;
import com.youlai.auth.domain.OAuthToken;
import com.youlai.auth.domain.UserInfo;
import com.youlai.auth.service.IAuthService;
import com.youlai.common.constant.AuthConstants;
import com.youlai.common.result.Result;
import com.youlai.common.web.util.JwtUtils;
@ -37,15 +34,14 @@ import java.util.concurrent.TimeUnit;
public class OAuthController {
private TokenEndpoint tokenEndpoint;
private IAuthService wechatAuthService;
private RedisTemplate redisTemplate;
private KeyPair keyPair;
@ApiOperation(value = "OAuth2认证", notes = "login")
@ApiImplicitParams({
@ApiImplicitParam(name = "grant_type", defaultValue = "password", value = "授权模式", required = true),
@ApiImplicitParam(name = "client_id", value = "Oauth2客户端ID(新版本需放置请求头)", required = true),
@ApiImplicitParam(name = "client_secret", value = "Oauth2客户端秘钥(新版本需放置请求头)", required = true),
@ApiImplicitParam(name = "client_id", value = "Oauth2客户端ID", required = true),
@ApiImplicitParam(name = "client_secret", value = "Oauth2客户端秘钥", required = true),
@ApiImplicitParam(name = "refresh_token", value = "刷新token"),
@ApiImplicitParam(name = "username", defaultValue = "admin", value = "登录用户名"),
@ApiImplicitParam(name = "password", defaultValue = "123456", value = "登录密码")
@ -74,14 +70,6 @@ public class OAuthController {
}
}
@ApiOperation(value = "微信授权登录")
@ApiImplicitParam(name = "code", value = "小程序授权code", paramType = "path")
@PostMapping("/wechat-token")
public Result wechatLogin(@PathVariable String code, @RequestBody UserInfo userInfo) {
OAuthToken token = wechatAuthService.login(code, userInfo);
return Result.success(token);
}
@ApiOperation(value = "注销", notes = "logout")
@DeleteMapping("/logout")
public Result logout() {

View File

@ -1,37 +0,0 @@
package com.youlai.auth.domain;
import com.youlai.auth.common.jwt.JwtPayloadBuilder;
import lombok.*;
import java.util.Set;
/**
* 描述: [自定义token]
* 创建时间: 2021/6/8
*
* @author hxr
* @version 1.0.0
* @update [序号][日期YYYY-MM-DD] [更改人姓名][变更描述]
*/
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
public class OAuthToken {
private String access_token;
private String token_type = "bearer";
public OAuthToken accessToken(String accessToken) {
this.access_token = accessToken;
return this;
}
public OAuthToken tokenType(String tokenType) {
this.token_type = tokenType;
return this;
}
}

View File

@ -3,9 +3,9 @@ package com.youlai.auth.security.config;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSONUtil;
import com.youlai.auth.security.core.userdetails.system.SysUserDetails;
import com.youlai.auth.security.core.clientdetails.ClientDetailsServiceImpl;
import com.youlai.auth.security.core.userdetails.system.SysUserDetailsServiceImpl;
import com.youlai.auth.security.core.userdetails.system.SysUserDetails;
import com.youlai.auth.security.extension.wechat.WechatTokenGranter;
import com.youlai.common.result.Result;
import com.youlai.common.result.ResultCode;
import lombok.AllArgsConstructor;
@ -16,14 +16,13 @@ import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.provider.CompositeTokenGranter;
import org.springframework.security.oauth2.provider.TokenGranter;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
@ -42,7 +41,7 @@ import java.util.*;
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
private AuthenticationManager authenticationManager;
private SysUserDetailsServiceImpl sysUserDetailsService;
private ClientDetailsServiceImpl clientDetailsService;
/**
@ -59,39 +58,29 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
// Token增强
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
List<TokenEnhancer> tokenEnhancers = new ArrayList<>();
tokenEnhancers.add(tokenEnhancer());
tokenEnhancers.add(jwtAccessTokenConverter());
tokenEnhancerChain.setTokenEnhancers(tokenEnhancers);
// 添加自定义授权模式
List<TokenGranter> granterList = new ArrayList<>(Arrays.asList(endpoints.getTokenGranter()));
granterList.add(new WechatTokenGranter(endpoints.getTokenServices(), endpoints.getClientDetailsService(), endpoints.getOAuth2RequestFactory(), authenticationManager));
CompositeTokenGranter compositeTokenGranter = new CompositeTokenGranter(granterList);
endpoints
.authenticationManager(authenticationManager)
.accessTokenConverter(jwtAccessTokenConverter())
.tokenEnhancer(tokenEnhancerChain)
// .userDetailsService(userDetailsService)
.tokenGranter(compositeTokenGranter)
// refresh token有两种使用方式重复使用(true)非重复使用(false)默认为true
// 1 重复使用access token过期刷新时 refresh token过期时间未改变仍以初次生成的时间为准
// 2 非重复使用access token过期刷新时 refresh token过期时间延续在refresh token有效期内刷新便永不失效达到无需再次登录的目的
.reuseRefreshTokens(true);
}
/**
* 重写 DaoAuthenticationProvider
*
* @return
*/
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setHideUserNotFoundExceptions(false); // 是否隐藏用户不存在异常默认:true-隐藏false-抛出异常
provider.setUserDetailsService(sysUserDetailsService);
provider.setPasswordEncoder(passwordEncoder());
return provider;
}
/**
* 使用非对称加密算法对token签名
*/
@ -103,7 +92,7 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
}
/**
* 从classpath下的密钥库中获取密钥对(公钥+私钥)
* 密钥库中获取密钥对(公钥+私钥)
*/
@Bean
public KeyPair keyPair() {
@ -128,17 +117,6 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
}
/**
* 密码编码器
* <p>
* 委托方式根据密码的前缀选择对应的encoder例如{bcypt}前缀->标识BCYPT算法加密{noop}->标识不使用任何加密即明文的方式
* 密码判读 DaoAuthenticationProvider#additionalAuthenticationChecks
*/
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
/**
* 自定义认证异常响应数据
*/

View File

@ -1,18 +1,31 @@
package com.youlai.auth.security.config;
import com.youlai.auth.security.core.userdetails.member.MemberUserDetailsServiceImpl;
import com.youlai.auth.security.core.userdetails.system.SysUserDetailsServiceImpl;
import com.youlai.auth.security.extension.wechat.WechatAuthenticationProvider;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
@Slf4j
@RequiredArgsConstructor
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final UserDetailsService sysUserDetailsService;
private final UserDetailsService memberUserDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
@ -25,7 +38,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
}
/**
* 认证管理中心
* 认证管理对象
*
* @return
* @throws Exception
@ -35,5 +48,40 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
return super.authenticationManagerBean();
}
@Override
public void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(wechatAuthenticationProvider())
.authenticationProvider(daoAuthenticationProvider());
}
@Bean
public WechatAuthenticationProvider wechatAuthenticationProvider() {
WechatAuthenticationProvider provider = new WechatAuthenticationProvider();
provider.setUserDetailsService(memberUserDetailsService);
return provider;
}
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setHideUserNotFoundExceptions(false); // 是否隐藏用户不存在异常默认:true-隐藏false-抛出异常
provider.setUserDetailsService(sysUserDetailsService);
provider.setPasswordEncoder(passwordEncoder());
return provider;
}
/**
* 密码编码器
* <p>
* 委托方式根据密码的前缀选择对应的encoder例如{bcypt}前缀->标识BCYPT算法加密{noop}->标识不使用任何加密即明文的方式
* 密码判读 DaoAuthenticationProvider#additionalAuthenticationChecks
*/
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
}

View File

@ -20,6 +20,7 @@ import java.util.Collection;
public class MemberUserDetails implements UserDetails {
private Long userId;
private String openId;
private Boolean enabled;
private Collection<SimpleGrantedAuthority> authorities;
@ -31,11 +32,11 @@ public class MemberUserDetails implements UserDetails {
* @param member 小程序会员用户认证信息
*/
public MemberUserDetails(MemberAuthDTO member) {
this.setUserId(member.getId());
this.setUserId(member.getUserId());
this.setOpenId(member.getOpenId());
this.setEnabled(GlobalConstants.STATUS_YES.equals(member.getStatus()));
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.authorities;
@ -48,7 +49,7 @@ public class MemberUserDetails implements UserDetails {
@Override
public String getUsername() {
return null;
return this.openId;
}
@Override

View File

@ -1,10 +1,13 @@
package com.youlai.auth.security.core.userdetails.member;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.youlai.common.result.Result;
import com.youlai.common.result.ResultCode;
import com.youlai.mall.ums.api.MemberFeignClient;
import com.youlai.mall.ums.pojo.dto.MemberAuthDTO;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.authentication.DisabledException;
@ -19,21 +22,33 @@ import org.springframework.stereotype.Service;
*
* @author <a href="mailto:xianrui0365@163.com">xianrui</a>
*/
@Service
@Service("memberUserDetailsService")
@Slf4j
@RequiredArgsConstructor
public class MemberUserDetailsServiceImpl implements UserDetailsService {
private final MemberFeignClient memberFeignClient;
private final WxMaService wxMaService;
@SneakyThrows
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
public UserDetails loadUserByUsername(String code) throws UsernameNotFoundException {
MemberUserDetails userDetails = null;
Result<MemberAuthDTO> result = memberFeignClient.loadUserByOpenId(username);
WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(code);
String openid = sessionInfo.getOpenid();
Result<MemberAuthDTO> result = memberFeignClient.loadUserByOpenId(openid);
if (Result.isSuccess(result)) {
MemberAuthDTO member = result.getData();
if (null != member) {
userDetails = new MemberUserDetails(member);
} else { // 微信用户不存在同步微信用户信息注册为小程序会员
//wxMaService.getUserService().getUserInfo()
}
}
if (userDetails == null) {

View File

@ -52,18 +52,6 @@ public class SysUserDetails implements UserDetails {
}
}
/**
* 小程序会员用户体系
*
* @param member 小程序会员用户认证信息
*/
public SysUserDetails(MemberAuthDTO member) {
this.setUserId(member.getId());
this.setUsername(member.getUsername());
this.setEnabled(GlobalConstants.STATUS_YES.equals(member.getStatus()));
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.authorities;

View File

@ -19,7 +19,7 @@ import org.springframework.stereotype.Service;
*
* @author <a href="mailto:xianrui0365@163.com">xianrui</a>
*/
@Service
@Service("sysUserDetailsService")
@Slf4j
@RequiredArgsConstructor
public class SysUserDetailsServiceImpl implements UserDetailsService {

View File

@ -1,14 +1,9 @@
package com.youlai.auth.domain;
import lombok.Data;
package com.youlai.auth.security.extension.wechat;
/**
* 描述: [微信用户信息]
* 创建时间: 2021/6/8
*
* @author hxr
* @author <a href="mailto:xianrui0365@163.com">xianrui</a>
* @date 2021/9/29
*/
@Data
public class UserInfo {
private String avatarUrl;

View File

@ -1,20 +1,25 @@
package com.youlai.auth.security.extension.wechat;
import com.youlai.auth.security.core.userdetails.member.MemberUserDetailsServiceImpl;
import lombok.Data;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
/**
* @author <a href="mailto:xianrui0365@163.com">xianrui</a>
* @date 2021/9/25
*/
@Data
public class WechatAuthenticationProvider implements AuthenticationProvider {
private MemberUserDetailsServiceImpl memberUserDetailsService;
private UserDetailsService userDetailsService;
/**
* 用户认证
*
* @param authentication
* @return
* @throws AuthenticationException
@ -22,10 +27,10 @@ public class WechatAuthenticationProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
WechatAuthenticationToken authenticationToken = (WechatAuthenticationToken) authentication;
String openId = (String) authenticationToken.getPrincipal();
UserDetails userDetails = memberUserDetailsService.loadUserByUsername(openId);
String code = (String) authenticationToken.getPrincipal();
UserDetails userDetails = userDetailsService.loadUserByUsername(code);
WechatAuthenticationToken result = new WechatAuthenticationToken(openId, userDetails.getAuthorities());
WechatAuthenticationToken result = new WechatAuthenticationToken(userDetails.getUsername(), userDetails.getAuthorities());
result.setDetails(authentication.getDetails());
return result;
}

View File

@ -15,12 +15,23 @@ public class WechatAuthenticationToken extends AbstractAuthenticationToken {
private final Object principal;
/**
* 账号校验之前的token构建
*
* @param principal
*/
public WechatAuthenticationToken(Object principal) {
super(null);
this.principal = principal;
setAuthenticated(false);
}
/**
* 账号校验成功之后的token构建
*
* @param principal
* @param authorities
*/
public WechatAuthenticationToken(Object principal, Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
@ -37,7 +48,6 @@ public class WechatAuthenticationToken extends AbstractAuthenticationToken {
return this.principal;
}
@Override
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
Assert.isTrue(!isAuthenticated, "Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");

View File

@ -19,8 +19,8 @@ public class WechatTokenGranter extends AbstractTokenGranter {
private static final String GRANT_TYPE = "wechat";
private final AuthenticationManager authenticationManager;
protected WechatTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, String grantType, AuthenticationManager authenticationManager) {
super(tokenServices, clientDetailsService, requestFactory, grantType);
public WechatTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, AuthenticationManager authenticationManager) {
super(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE);
this.authenticationManager = authenticationManager;
}
@ -28,21 +28,27 @@ public class WechatTokenGranter extends AbstractTokenGranter {
protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
Map<String, String> parameters = new LinkedHashMap(tokenRequest.getRequestParameters());
String openId = parameters.get("openId");
Authentication userAuth = new WechatAuthenticationToken(openId);
String code = parameters.get("code");
String rawData = parameters.get("rawData");
parameters.remove("code");
parameters.remove("rawData");
Authentication userAuth = new WechatAuthenticationToken(code); // 未认证状态
((AbstractAuthenticationToken) userAuth).setDetails(parameters);
try {
userAuth = this.authenticationManager.authenticate(userAuth); // 参数校验
userAuth = this.authenticationManager.authenticate(userAuth); // 认证中
} catch (Exception e) {
throw new InvalidGrantException(e.getMessage());
}
if (userAuth != null && userAuth.isAuthenticated()) {
if (userAuth != null && userAuth.isAuthenticated()) { // 认证成功
OAuth2Request storedOAuth2Request = this.getRequestFactory().createOAuth2Request(client, tokenRequest);
return new OAuth2Authentication(storedOAuth2Request, userAuth);
} else {
throw new InvalidGrantException("Could not authenticate user: " + openId);
} else { // 认证失败
throw new InvalidGrantException("Could not authenticate code: " + code);
}
}
}

View File

@ -1,19 +0,0 @@
package com.youlai.auth.service;
import com.youlai.auth.domain.OAuthToken;
import com.youlai.auth.domain.UserInfo;
import java.util.Map;
/**
* 描述: [类型描述]
* 创建时间: 2021/6/8
*
* @author hxr
* @version 1.0.0
* @update [序号][日期YYYY-MM-DD] [更改人姓名][变更描述]
*/
public interface IAuthService {
OAuthToken login(String code, UserInfo userInfo);
}

View File

@ -1,71 +0,0 @@
package com.youlai.auth.service.impl;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import com.youlai.auth.common.jwt.JwtGenerator;
import com.youlai.auth.domain.OAuthToken;
import com.youlai.auth.domain.UserInfo;
import com.youlai.auth.service.IAuthService;
import com.youlai.common.constant.AuthConstants;
import com.youlai.common.result.Result;
import com.youlai.common.result.ResultCode;
import com.youlai.mall.ums.api.MemberFeignClient;
import com.youlai.mall.ums.pojo.entity.UmsMember;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* @author haoxr
* @description 微信小程序认证接口
* @createTime 2021/5/20 23:37
*/
@Service
@AllArgsConstructor
public class WechatAuthServiceImpl implements IAuthService {
private MemberFeignClient memberFeignClient;
private WxMaService wxMaService;
private JwtGenerator jwtGenerator;
@SneakyThrows
@Override
public OAuthToken login(String code, UserInfo userInfo) {
// 微信小程序的授权code获取openid
WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(code);
String openid = sessionInfo.getOpenid();
Result<UmsMember> result = memberFeignClient.getByOpenid(openid);
UmsMember member;
if (ResultCode.USER_NOT_EXIST.getCode().equals(result.getCode())) {
// 用户不存在注册成为新用户
member = new UmsMember();
BeanUtil.copyProperties(userInfo, member);
member.setOpenid(openid);
Result<Long> addRes = memberFeignClient.add(member);
Assert.isTrue(ResultCode.SUCCESS.getCode().equals(addRes.getCode()), "微信用户注册失败");
member.setId(addRes.getData()); // 新增后有了会员ID
} else {
member = result.getData();
}
// 自定义JWT生成
// 1. JWT授权一般存放用户的角色标识用于资源服务器网关鉴权
Set<String> authorities = new HashSet<>();
// 2. JWT增强携带用户ID等信息
Map<String, String> additional = new HashMap<>();
additional.put(AuthConstants.USER_ID_KEY, Convert.toStr(member.getId()));
String accessToken = jwtGenerator.createAccessToken(authorities, additional);
OAuthToken token = new OAuthToken().accessToken(accessToken);
return token;
}
}