package com.mzl.flower.web.login; import cn.hutool.core.util.StrUtil; import com.mzl.flower.base.BaseController; import com.mzl.flower.base.R; import com.mzl.flower.base.ReturnDataDTO; import com.mzl.flower.base.cache.StringCacheClient; import com.mzl.flower.config.exception.BaseException; import com.mzl.flower.config.exception.ValidationException; import com.mzl.flower.config.security.token.PhoneAuthenticationToken; import com.mzl.flower.config.security.token.SupAuthenticationToken; import com.mzl.flower.constant.Constants; import com.mzl.flower.dto.request.UserLoginDTO; import com.mzl.flower.entity.system.User; import com.mzl.flower.service.login.LoginService; import com.mzl.flower.service.system.UserService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.authentication.AuthenticationDetailsSource; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.common.OAuth2RefreshToken; import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; @Slf4j @RestController @RequestMapping("/api") @Api(value = "供应商登录", tags = "供应商登录") public class SupplierLoginController extends BaseController { private AuthenticationDetailsSource authenticationDetailsSource = new WebAuthenticationDetailsSource(); @Autowired private AuthenticationManager authenticationManager; @Autowired private LoginService loginService; @Autowired private StringCacheClient stringCacheClient; @Autowired private UserService userService; @Autowired private TokenStore tokenStore; public static final String SMS_CODE_KEY = "SMS-CODE-KEY"; public static final String TOKEN_KEY = "TOKEN-KEY"; public static final String SEPARATOR = ":"; @PostMapping("/login/supplier") @ApiOperation(value = "供应商账号密码登录", notes = "供应商账号密码登录") public ResponseEntity> loginPerson(HttpServletRequest request , @RequestBody UserLoginDTO loginDTO) { String username = loginDTO.getUsername(); String password = loginDTO.getPassword(); if (StringUtils.isBlank(username)) { throw new ValidationException("用户名不能为空"); } if (StringUtils.isBlank(password)) { throw new ValidationException("密码不能为空"); } User user = userService.findByTel(username, Constants.USER_TYPE.supplier.name()); if(user == null){ throw new ValidationException("用户不存在"); } String tokenCache = stringCacheClient.get(TOKEN_KEY + SEPARATOR + user.getId()); if (StringUtils.isNotBlank(tokenCache)) { //强制删除token,下线 removeToken(tokenCache,user.getId()); } try { SupAuthenticationToken authRequest = new SupAuthenticationToken(username, password); authRequest.setDetails(authenticationDetailsSource.buildDetails(request)); Authentication authentication = authenticationManager.authenticate(authRequest); OAuth2AccessToken token = loginService.getAccessToken(authentication,Constants.USER_TYPE.supplier.name()); stringCacheClient.set(TOKEN_KEY + SEPARATOR + user.getId(),token.getValue()); return returnData(R.SUCCESS.getCode(),token); }catch (BadCredentialsException e){ throw new ValidationException("用户名或密码错误"); }catch (UsernameNotFoundException e){ throw new ValidationException("用户不存在"); }catch (Exception e) { log.error(e.getMessage(), e); throw new BaseException(R.RUNTIME_EXCEPTION.getCode(),"登录错误"); } } @PostMapping("/login/supplier/phone") @ApiOperation(value = "手机验证码登录系统", notes = "手机验证码登录系统") public ResponseEntity> loginPhone(HttpServletRequest request, @RequestBody UserLoginDTO loginDTO) { String tel = loginDTO.getUsername(); String smsCode = loginDTO.getSmsCode(); if (StringUtils.isBlank(tel)) { throw new ValidationException("手机号码不能为空"); } if (StringUtils.isBlank(smsCode)) { throw new ValidationException("手机验证码不能为空"); } //从缓存中获取验证码 String smsCacheCode = stringCacheClient.get(SMS_CODE_KEY + SEPARATOR + Constants.USER_TYPE.supplier.name() + SEPARATOR + tel); if (!StringUtils.equals(smsCode, smsCacheCode)) { throw new ValidationException("手机验证码不正确"); } User user = userService.findByTel(tel, Constants.USER_TYPE.supplier.name()); if(user == null){ throw new ValidationException("用户不存在"); } String tokenCache = stringCacheClient.get(TOKEN_KEY + SEPARATOR + user.getId()); if (StringUtils.isNotBlank(tokenCache)) { //强制删除token,下线 removeToken(tokenCache,user.getId()); } try { PhoneAuthenticationToken authRequest = new PhoneAuthenticationToken(tel, smsCode, Constants.USER_TYPE.supplier.name()); authRequest.setDetails(authenticationDetailsSource.buildDetails(request)); Authentication authentication = authenticationManager.authenticate(authRequest); OAuth2AccessToken token = loginService.getAccessToken(authentication, Constants.USER_TYPE.supplier.name()); //删除缓存中的验证码 stringCacheClient.delete(SMS_CODE_KEY + SEPARATOR + Constants.USER_TYPE.supplier.name() + SEPARATOR + tel); stringCacheClient.set(TOKEN_KEY + SEPARATOR + user.getId(),token.getValue()); return returnData(R.SUCCESS.getCode(),token); }catch (UsernameNotFoundException e){ throw new ValidationException("手机号未注册"); }catch (Exception e) { log.error(e.getMessage(), e); throw new BaseException(R.RUNTIME_EXCEPTION.getCode(),"登录错误"); } } public void removeToken(String token,String userId) { if (StringUtils.isNotBlank(token) && StringUtils.isNotBlank(userId)) { stringCacheClient.delete(TOKEN_KEY + SEPARATOR + userId); String tokenValue = token.replace(OAuth2AccessToken.BEARER_TYPE, StrUtil.EMPTY).trim(); OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue); if (accessToken != null && StringUtils.isNotBlank(accessToken.getValue())) { tokenStore.removeAccessToken(accessToken); OAuth2RefreshToken refreshToken = accessToken.getRefreshToken(); tokenStore.removeRefreshToken(refreshToken); } } } }