From 2e4fdf551c1ca90b5c19df212d0a713e184c55d3 Mon Sep 17 00:00:00 2001 From: haoxr <1490493387@qq.com> Date: Tue, 13 Oct 2020 01:09:26 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=E5=BE=AE=E4=BF=A1=E8=AE=A4=E8=AF=81?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../youlai/mall/ums/api/entity/UmsMember.java | 5 +- .../ums/api/feign/RemoteUmsMemberService.java | 2 +- .../youlai/auth/config/WebSecurityConfig.java | 2 +- .../auth/controller/AuthController.java | 74 ++++++- .../auth/controller/WxOAuthController.java | 194 ------------------ .../auth/service/UserDetailsServiceImpl.java | 14 +- 6 files changed, 87 insertions(+), 204 deletions(-) delete mode 100644 youlai-auth/src/main/java/com/youlai/auth/controller/WxOAuthController.java diff --git a/mall-ums/mall-ums-api/src/main/java/com/youlai/mall/ums/api/entity/UmsMember.java b/mall-ums/mall-ums-api/src/main/java/com/youlai/mall/ums/api/entity/UmsMember.java index a6fa84b7e..9a6d90cc1 100644 --- a/mall-ums/mall-ums-api/src/main/java/com/youlai/mall/ums/api/entity/UmsMember.java +++ b/mall-ums/mall-ums-api/src/main/java/com/youlai/mall/ums/api/entity/UmsMember.java @@ -3,13 +3,16 @@ package com.youlai.mall.ums.api.entity; import lombok.Builder; import lombok.Data; +import lombok.experimental.Accessors; import java.time.LocalDate; @Data -@Builder +@Accessors(chain = true) public class UmsMember { + + private Long id; private String username; diff --git a/mall-ums/mall-ums-api/src/main/java/com/youlai/mall/ums/api/feign/RemoteUmsMemberService.java b/mall-ums/mall-ums-api/src/main/java/com/youlai/mall/ums/api/feign/RemoteUmsMemberService.java index 6e6d4f088..4d06f6a86 100644 --- a/mall-ums/mall-ums-api/src/main/java/com/youlai/mall/ums/api/feign/RemoteUmsMemberService.java +++ b/mall-ums/mall-ums-api/src/main/java/com/youlai/mall/ums/api/feign/RemoteUmsMemberService.java @@ -16,7 +16,7 @@ public interface RemoteUmsMemberService { Result loadMemberByOpenid(@PathVariable String openid); @PostMapping("/members") - Result add(@RequestBody UmsMember umsMember); + Result add(@RequestBody UmsMember member); } diff --git a/youlai-auth/src/main/java/com/youlai/auth/config/WebSecurityConfig.java b/youlai-auth/src/main/java/com/youlai/auth/config/WebSecurityConfig.java index 3a49d8eb6..b894b3b9a 100644 --- a/youlai-auth/src/main/java/com/youlai/auth/config/WebSecurityConfig.java +++ b/youlai-auth/src/main/java/com/youlai/auth/config/WebSecurityConfig.java @@ -19,7 +19,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { http .authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll() .and() - .authorizeRequests().antMatchers("/rsa/publicKey","/oauth/logout").permitAll().anyRequest().authenticated() + .authorizeRequests().antMatchers("/rsa/publicKey").permitAll().anyRequest().authenticated() .and() .csrf().disable(); } diff --git a/youlai-auth/src/main/java/com/youlai/auth/controller/AuthController.java b/youlai-auth/src/main/java/com/youlai/auth/controller/AuthController.java index 925b5eb74..d824bcd13 100644 --- a/youlai-auth/src/main/java/com/youlai/auth/controller/AuthController.java +++ b/youlai-auth/src/main/java/com/youlai/auth/controller/AuthController.java @@ -8,6 +8,7 @@ import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.youlai.auth.domain.Oauth2Token; import com.youlai.common.core.constant.AuthConstants; +import com.youlai.common.core.constant.Constants; import com.youlai.common.core.result.Result; import com.youlai.common.core.result.ResultCode; import com.youlai.common.web.exception.BizException; @@ -54,13 +55,17 @@ public class AuthController { @ApiImplicitParam(name = "client_secret", defaultValue = "123456", value = "Oauth2客户端秘钥", required = true), @ApiImplicitParam(name = "refresh_token", value = "刷新token"), @ApiImplicitParam(name = "username", defaultValue = "admin", value = "登录用户名"), - @ApiImplicitParam(name = "password", defaultValue = "123456", value = "登录密码") + @ApiImplicitParam(name = "password", defaultValue = "123456", value = "登录密码"), + + @ApiImplicitParam(name = "code", value = "小程序code"), + @ApiImplicitParam(name = "encryptedData", value = "包括敏感数据在内的完整用户信息的加密数据"), + @ApiImplicitParam(name = "iv", value = "加密算法的初始向量"), }) @PostMapping("/token") public Result postAccessToken( @ApiIgnore Principal principal, @ApiIgnore @RequestParam Map parameters - ) throws HttpRequestMethodNotSupportedException { + ) throws HttpRequestMethodNotSupportedException, WxErrorException { String clientId = parameters.get("client_id"); @@ -68,6 +73,11 @@ public class AuthController { throw new BizException("客户端ID不能为空"); } + // 微信小程序端认证处理 + if(AuthConstants.WEAPP_CLIENT_ID.equals(clientId)){ + return this.handleForWxAppAuth(principal,parameters); + } + OAuth2AccessToken oAuth2AccessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody(); Oauth2Token oauth2Token = Oauth2Token.builder() .token(oAuth2AccessToken.getValue()) @@ -78,6 +88,8 @@ public class AuthController { return Result.success(oauth2Token); } + + @DeleteMapping("/logout") public Result logout(HttpServletRequest request) { String payload = request.getHeader(AuthConstants.JWT_PAYLOAD_KEY); @@ -94,4 +106,62 @@ public class AuthController { redisTemplate.opsForValue().set(AuthConstants.TOKEN_BLACKLIST_PREFIX + jti, null, (exp - currentTimeSeconds), TimeUnit.SECONDS); return Result.success(); } + + + private Result handleForWxAppAuth(Principal principal, Map parameters) throws WxErrorException, HttpRequestMethodNotSupportedException { + + String code = parameters.get("code"); + if (StrUtil.isBlank(code)) { + throw new BizException("code不能为空"); + } + + WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(code); + String openid = session.getOpenid(); + String sessionKey = session.getSessionKey(); + + Result result = remoteUmsMemberService.loadMemberByOpenid(openid); + if (!ResultCode.SUCCESS.getCode().equals(result.getCode())) { + throw new BizException("获取会员信息失败"); + } + MemberDTO memberDTO = result.getData(); + String username; + if (memberDTO == null) { // 微信授权登录 会员信息不存在时 注册会员 + String encryptedData = parameters.get("encryptedData"); + String iv = parameters.get("iv"); + + WxMaUserInfo userInfo = wxService.getUserService().getUserInfo(sessionKey, encryptedData, iv); + if (userInfo == null) { + throw new BizException("获取用户信息失败"); + } + UmsMember member = new UmsMember() + .setNickname(userInfo.getNickName()) + .setAvatar(userInfo.getAvatarUrl()) + .setGender(Integer.valueOf(userInfo.getGender())) + .setOpenid(openid) + .setUsername(openid) + .setPassword(passwordEncoder.encode(openid).replace(AuthConstants.BCRYPT, Strings.EMPTY)) // 加密密码移除前缀加密方式 {bcrypt} + .setStatus(Constants.STATUS_NORMAL_VALUE); + + Result res = remoteUmsMemberService.add(member); + if (!ResultCode.SUCCESS.getCode().equals(res.getCode())) { + throw new BizException("注册会员失败"); + } + username = openid; + } else { + username = memberDTO.getUsername(); + } + + parameters.put("username", username); + parameters.put("password", username); + + OAuth2AccessToken oAuth2AccessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody(); + Oauth2Token oauth2Token = Oauth2Token.builder() + .token(oAuth2AccessToken.getValue()) + .refreshToken(oAuth2AccessToken.getRefreshToken().getValue()) + .expiresIn(oAuth2AccessToken.getExpiresIn()) + .build(); + return Result.success(oauth2Token); + + } + } diff --git a/youlai-auth/src/main/java/com/youlai/auth/controller/WxOAuthController.java b/youlai-auth/src/main/java/com/youlai/auth/controller/WxOAuthController.java deleted file mode 100644 index 319b4aaac..000000000 --- a/youlai-auth/src/main/java/com/youlai/auth/controller/WxOAuthController.java +++ /dev/null @@ -1,194 +0,0 @@ -package com.youlai.auth.controller; - -import cn.binarywang.wx.miniapp.api.WxMaService; -import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; -import cn.binarywang.wx.miniapp.bean.WxMaUserInfo; -import cn.hutool.core.util.StrUtil; -import cn.hutool.json.JSONObject; -import cn.hutool.json.JSONUtil; -import com.youlai.auth.domain.Oauth2Token; -import com.youlai.common.core.constant.AuthConstants; -import com.youlai.common.core.result.Result; -import com.youlai.common.core.result.ResultCode; -import com.youlai.common.web.exception.BizException; -import com.youlai.mall.ums.api.dto.MemberDTO; -import com.youlai.mall.ums.api.entity.UmsMember; -import com.youlai.mall.ums.api.feign.RemoteUmsMemberService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; -import io.swagger.annotations.ApiOperation; -import lombok.AllArgsConstructor; -import me.chanjar.weixin.common.error.WxErrorException; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.oauth2.common.OAuth2AccessToken; -import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint; -import org.springframework.web.HttpRequestMethodNotSupportedException; -import org.springframework.web.bind.annotation.*; -import springfox.documentation.annotations.ApiIgnore; - -import javax.servlet.http.HttpServletRequest; -import java.security.Principal; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -@Api(tags = "认证中心") -@RestController -@RequestMapping("/wxoauth") -@AllArgsConstructor -public class WxOAuthController { - - private TokenEndpoint tokenEndpoint; - private RedisTemplate redisTemplate; - private WxMaService wxService; - private RemoteUmsMemberService remoteUmsMemberService; - private PasswordEncoder passwordEncoder; - - - @ApiOperation("Oauth2获取token") - @ApiImplicitParams({ - @ApiImplicitParam(name = "grant_type", defaultValue = "password", value = "授权模式", required = true), - @ApiImplicitParam(name = "client_id", defaultValue = "client", value = "Oauth2客户端ID", required = true), - @ApiImplicitParam(name = "client_secret", defaultValue = "123456", value = "Oauth2客户端秘钥", required = true), - @ApiImplicitParam(name = "refresh_token", value = "刷新token"), - - @ApiImplicitParam(name = "code", value = "小程序code"), - @ApiImplicitParam(name = "encryptedData", value = "包括敏感数据在内的完整用户信息的加密数据"), - @ApiImplicitParam(name = "iv", value = "加密算法的初始向量"), - }) - @PostMapping("/token") - public Result postAccessToken( - @ApiIgnore Principal principal, - @ApiIgnore @RequestParam Map parameters - ) throws HttpRequestMethodNotSupportedException, WxErrorException { - - String clientId = parameters.get("client_id"); - - if (StrUtil.isBlank(clientId)) { - throw new BizException("客户端ID不能为空"); - } - - String code = parameters.get("code"); - if (StrUtil.isBlank(code)) { - throw new BizException("code不能为空"); - } - - WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(code); - String openid = session.getOpenid(); - String sessionKey = session.getSessionKey(); - - Result result = remoteUmsMemberService.loadMemberByOpenid(openid); - if(ResultCode.SUCCESS.getCode().equals(result.getCode())){ - MemberDTO memberDTO = result.getData(); - if(memberDTO!=null){ - - } - - - } - - WxMaUserInfo userInfo; - UmsMember member; - if (memberDTO == null || memberDTO.getId() == null) { - // 注册会员 - String encryptedData = parameters.get("encryptedData"); - String iv = parameters.get("iv"); - - userInfo = wxService.getUserService().getUserInfo(sessionKey, encryptedData, iv); - member = UmsMember.builder() - .nickname(userInfo.getNickName()) - .avatar(userInfo.getAvatarUrl()) - .gender(Integer.valueOf(userInfo.getGender())) - .openid(openid) - .username(openid) - //.password(passwordEncoder.encode(openid).replace(AuthConstants.BCRYPT, Strings.EMPTY)) // 加密密码移除前缀加密方式 {bcrypt} - .build(); - Result result = remoteUmsMemberService.add(member); - if (!ResultCode.SUCCESS.getCode().equals(result.getCode())) { - throw new BizException("注册会员失败"); - } - } - parameters.put("username", username); - parameters.put("password", null); - - - - OAuth2AccessToken oAuth2AccessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody(); - Oauth2Token oauth2Token = Oauth2Token.builder() - .token(oAuth2AccessToken.getValue()) - .refreshToken(oAuth2AccessToken.getRefreshToken().getValue()) - .expiresIn(oAuth2AccessToken.getExpiresIn()) - .build(); - - return Result.success(oauth2Token); - } - - @DeleteMapping("/logout") - public Result logout(HttpServletRequest request) { - String payload = request.getHeader(AuthConstants.JWT_PAYLOAD_KEY); - JSONObject jsonObject = JSONUtil.parseObj(payload); - - String jti = jsonObject.getStr("jti"); // JWT唯一标识 - long exp = jsonObject.getLong("exp"); // JWT过期时间戳 - - long currentTimeSeconds = System.currentTimeMillis() / 1000; - - if (exp < currentTimeSeconds) { // token已过期,无需加入黑名单 - return Result.success(); - } - redisTemplate.opsForValue().set(AuthConstants.TOKEN_BLACKLIST_PREFIX + jti, null, (exp - currentTimeSeconds), TimeUnit.SECONDS); - return Result.success(); - } - - - private WxMaUserInfo handleForWeappAuth(Principal principal, Map parameters) { - - try { - String code = parameters.get("code"); - if (StrUtil.isBlank(code)) { - throw new BizException("code不能为空"); - } - WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(code); - String openid = session.getOpenid(); - String sessionKey = session.getSessionKey(); - String username = null; - - MemberDTO memberDTO = remoteUmsMemberService.loadMemberByOpenid(openid); - WxMaUserInfo userInfo; - if (memberDTO == null || memberDTO.getId() == null) { - // 注册会员 - String encryptedData = parameters.get("encryptedData"); - String iv = parameters.get("iv"); - - userInfo = wxService.getUserService().getUserInfo(sessionKey, encryptedData, iv); - UmsMember member = UmsMember.builder() - .nickname(userInfo.getNickName()) - .avatar(userInfo.getAvatarUrl()) - .gender(Integer.valueOf(userInfo.getGender())) - .openid(openid) - .username(openid) - //.password(passwordEncoder.encode(openid).replace(AuthConstants.BCRYPT, Strings.EMPTY)) // 加密密码移除前缀加密方式 {bcrypt} - .build(); - Result result = remoteUmsMemberService.add(member); - if (!ResultCode.SUCCESS.getCode().equals(result.getCode())) { - throw new BizException("注册会员失败"); - } - username = member.getUsername(); - } else { - userInfo = new WxMaUserInfo(); - userInfo.setAvatarUrl(memberDTO.getAvatar()); - userInfo.setNickName(memberDTO.getNickname()); - username = memberDTO.getUsername(); - } - parameters.put("username", username); - parameters.put("password", null); - return userInfo; - } catch (WxErrorException e) { - e.printStackTrace(); - throw new BizException("auth failed"); - } - - } - -} diff --git a/youlai-auth/src/main/java/com/youlai/auth/service/UserDetailsServiceImpl.java b/youlai-auth/src/main/java/com/youlai/auth/service/UserDetailsServiceImpl.java index 7005fd665..4b05cfa3a 100644 --- a/youlai-auth/src/main/java/com/youlai/auth/service/UserDetailsServiceImpl.java +++ b/youlai-auth/src/main/java/com/youlai/auth/service/UserDetailsServiceImpl.java @@ -4,6 +4,8 @@ import com.youlai.admin.api.dto.UserDTO; import com.youlai.admin.api.feign.RemoteAdminService; import com.youlai.auth.domain.User; import com.youlai.common.core.constant.AuthConstants; +import com.youlai.common.core.result.Result; +import com.youlai.common.core.result.ResultCode; import com.youlai.mall.ums.api.dto.MemberDTO; import com.youlai.mall.ums.api.feign.RemoteUmsMemberService; import lombok.AllArgsConstructor; @@ -36,18 +38,20 @@ public class UserDetailsServiceImpl implements UserDetailsService { User user = null; switch (clientId) { case AuthConstants.ADMIN_CLIENT_ID: // 后台用户 - UserDTO userDTO = remoteAdminService.loadUserByUsername(username); - if (userDTO == null) { + Result userResult = remoteAdminService.loadUserByUsername(username); + if (userResult == null || !ResultCode.SUCCESS.getCode().equals(userResult.getCode())) { throw new UsernameNotFoundException("用户不存在"); } + UserDTO userDTO = userResult.getData(); userDTO.setClientId(clientId); user = new User(userDTO); break; case AuthConstants.WEAPP_CLIENT_ID: // 小程序会员 - MemberDTO memberDTO = remoteUmsMemberService.loadMemberByOpenid(username); - if (memberDTO == null) { - throw new UsernameNotFoundException("用户不存在"); + Result memberResult = remoteUmsMemberService.loadMemberByOpenid(username); + if (memberResult == null || !ResultCode.SUCCESS.getCode().equals(memberResult.getCode())) { + throw new UsernameNotFoundException("会员不存在"); } + MemberDTO memberDTO = memberResult.getData(); memberDTO.setClientId(clientId); user = new User(memberDTO); break;