diff --git a/README.md b/README.md index 36456ed..d430fb6 100644 --- a/README.md +++ b/README.md @@ -303,11 +303,13 @@ RestTemplate服务间调用 | - 删除记录功能 - 浏览列表展示 -> **会员登录** +> **会员登录注册** - 登录功能:https登录 -- 注册功能 - +- 注册功能:用户名、密码、手机号、手机验证码 +- 获取验证码:后台生成验证码,验证码绑定手机号 +- 忘记密码:手机号、短信验证码、新密码 +- 登出功能 diff --git a/mall-portal/pom.xml b/mall-portal/pom.xml index 50ad813..f6381d8 100644 --- a/mall-portal/pom.xml +++ b/mall-portal/pom.xml @@ -38,6 +38,10 @@ org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-security + org.springframework.boot spring-boot-starter-test diff --git a/mall-portal/src/main/java/com/macro/mall/portal/config/SecurityConfig.java b/mall-portal/src/main/java/com/macro/mall/portal/config/SecurityConfig.java new file mode 100644 index 0000000..77a0026 --- /dev/null +++ b/mall-portal/src/main/java/com/macro/mall/portal/config/SecurityConfig.java @@ -0,0 +1,78 @@ +package com.macro.mall.portal.config; + +import com.macro.mall.model.UmsMember; +import com.macro.mall.portal.domain.MemberDetails; +import com.macro.mall.portal.service.UmsMemberService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.security.authentication.encoding.Md5PasswordEncoder; +import org.springframework.security.authentication.encoding.PasswordEncoder; +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.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; + +/** + * SpringSecurity的配置 + * Created by macro on 2018/8/3. + */ +@Configuration +@EnableWebSecurity +public class SecurityConfig extends WebSecurityConfigurerAdapter { + @Autowired + private UmsMemberService memberService; + @Override + protected void configure(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers(HttpMethod.GET, // 允许对于网站静态资源的无授权访问 + "/", + "/*.html", + "/favicon.ico", + "/**/*.html", + "/**/*.css", + "/**/*.js", + "/swagger-resources/**", + "/v2/api-docs/**" + ) + .permitAll() + .antMatchers(HttpMethod.OPTIONS)//跨域请求会先进行一次options请求 + .permitAll() + .antMatchers("/sso/*")// 对登录注册要允许匿名访问 + .permitAll() + .anyRequest()// 除上面外的所有请求全部需要鉴权认证 + .authenticated() + .and() + .csrf().disable(); + } + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(userDetailsService()) + .passwordEncoder(passwordEncoder()); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new Md5PasswordEncoder(); + } + + @Bean + public UserDetailsService userDetailsService() { + //获取登录用户信息 + return new UserDetailsService() { + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + UmsMember member = memberService.getByUsername(username); + if(member!=null){ + return new MemberDetails(member); + } + throw new UsernameNotFoundException("用户名或密码错误"); + } + }; + } +} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/controller/UmsMemberController.java b/mall-portal/src/main/java/com/macro/mall/portal/controller/UmsMemberController.java new file mode 100644 index 0000000..66e4938 --- /dev/null +++ b/mall-portal/src/main/java/com/macro/mall/portal/controller/UmsMemberController.java @@ -0,0 +1,68 @@ +package com.macro.mall.portal.controller; + +import com.macro.mall.model.UmsMember; +import com.macro.mall.portal.domain.CommonResult; +import com.macro.mall.portal.service.UmsMemberService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +/** + * 会员登录注册管理Controller + * Created by macro on 2018/8/3. + */ +@Controller +@Api(tags = "UmsMemberController", description = "会员登录注册管理") +@RequestMapping("/sso") +public class UmsMemberController { + @Autowired + private UmsMemberService memberService; + @ApiOperation("登录") + @RequestMapping(value = "/login", method = RequestMethod.POST) + @ResponseBody + public Object login(@RequestParam String username, @RequestParam String password) { + return memberService.login(username,password); + } + + @ApiOperation("注册") + @RequestMapping(value = "/register", method = RequestMethod.POST) + @ResponseBody + public Object register(@RequestParam String username, + @RequestParam String password, + @RequestParam String telephone, + @RequestParam String authCode) { + UmsMember member = memberService.register(username,password,telephone,authCode); + if(member!=null){ + return new CommonResult().success(member); + } + return new CommonResult().failed(); + } + + @ApiOperation("获取验证码") + @RequestMapping(value = "/getAuthCode", method = RequestMethod.GET) + @ResponseBody + public Object getAuthCode(@RequestParam String telephone) { + return memberService.generateAuthCode(telephone); + } + + @ApiOperation("修改密码") + @RequestMapping(value = "/updatePassword", method = RequestMethod.POST) + @ResponseBody + public Object updatePassword(@RequestParam String telephone, + @RequestParam String password, + @RequestParam String authCode) { + return null; + } + + @ApiOperation("登出操作") + @RequestMapping(value = "/logout", method = RequestMethod.POST) + @ResponseBody + public Object logout() { + return null; + } +} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/domain/CommonResult.java b/mall-portal/src/main/java/com/macro/mall/portal/domain/CommonResult.java index 4be915b..2d9abd4 100644 --- a/mall-portal/src/main/java/com/macro/mall/portal/domain/CommonResult.java +++ b/mall-portal/src/main/java/com/macro/mall/portal/domain/CommonResult.java @@ -30,6 +30,16 @@ public class CommonResult { return this; } + /** + * 普通成功返回 + */ + public CommonResult success(String message,Object data) { + this.code = SUCCESS; + this.message = message; + this.data = data; + return this; + } + /** * 返回分页成功数据 */ @@ -55,6 +65,12 @@ public class CommonResult { return this; } + public CommonResult failed(String message){ + this.code = FAILED; + this.message = message; + return this; + } + public int getCode() { return code; } diff --git a/mall-portal/src/main/java/com/macro/mall/portal/domain/MemberDetails.java b/mall-portal/src/main/java/com/macro/mall/portal/domain/MemberDetails.java new file mode 100644 index 0000000..5718757 --- /dev/null +++ b/mall-portal/src/main/java/com/macro/mall/portal/domain/MemberDetails.java @@ -0,0 +1,57 @@ +package com.macro.mall.portal.domain; + +import com.macro.mall.model.UmsMember; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Arrays; +import java.util.Collection; + +/** + * 会员详情封装 + * Created by macro on 2018/8/3. + */ +public class MemberDetails implements UserDetails { + private UmsMember umsMember; + + public MemberDetails(UmsMember umsMember) { + this.umsMember = umsMember; + } + + @Override + public Collection getAuthorities() { + //返回当前用户的权限 + return Arrays.asList(new SimpleGrantedAuthority("TEST")); + } + + @Override + public String getPassword() { + return umsMember.getPassword(); + } + + @Override + public String getUsername() { + return umsMember.getUsername(); + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return umsMember.getStatus()==1; + } +} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/UmsMemberService.java b/mall-portal/src/main/java/com/macro/mall/portal/service/UmsMemberService.java new file mode 100644 index 0000000..c1f3d85 --- /dev/null +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/UmsMemberService.java @@ -0,0 +1,32 @@ +package com.macro.mall.portal.service; + +import com.macro.mall.model.UmsMember; +import com.macro.mall.portal.domain.CommonResult; +import org.springframework.transaction.annotation.Transactional; + +/** + * 会员管理Service + * Created by macro on 2018/8/3. + */ +public interface UmsMemberService { + /** + * 根据用户名获取会员 + */ + UmsMember getByUsername(String username); + + /** + * 用户注册 + */ + @Transactional + UmsMember register(String username, String password, String telephone, String authCode); + + /** + * 登录操作 + */ + CommonResult login(String username, String password); + + /** + * 生成验证码 + */ + CommonResult generateAuthCode(String telephone); +} diff --git a/mall-portal/src/main/java/com/macro/mall/portal/service/impl/UmsMemberServiceImpl.java b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/UmsMemberServiceImpl.java new file mode 100644 index 0000000..1c58637 --- /dev/null +++ b/mall-portal/src/main/java/com/macro/mall/portal/service/impl/UmsMemberServiceImpl.java @@ -0,0 +1,100 @@ +package com.macro.mall.portal.service.impl; + +import com.macro.mall.mapper.UmsMemberLevelMapper; +import com.macro.mall.mapper.UmsMemberMapper; +import com.macro.mall.model.UmsMember; +import com.macro.mall.model.UmsMemberExample; +import com.macro.mall.model.UmsMemberLevel; +import com.macro.mall.model.UmsMemberLevelExample; +import com.macro.mall.portal.domain.CommonResult; +import com.macro.mall.portal.service.UmsMemberService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.authentication.encoding.PasswordEncoder; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.Date; +import java.util.List; + +/** + * 会员管理Service实现类 + * Created by macro on 2018/8/3. + */ +@Service +public class UmsMemberServiceImpl implements UmsMemberService { + @Autowired + private UmsMemberMapper memberMapper; + @Autowired + private UmsMemberLevelMapper memberLevelMapper; + @Autowired + private PasswordEncoder passwordEncoder; + @Autowired + private AuthenticationManager authenticationManager; + private static final Logger LOGGER = LoggerFactory.getLogger(UmsMemberServiceImpl.class); + + @Override + public UmsMember getByUsername(String username) { + UmsMemberExample example = new UmsMemberExample(); + example.createCriteria().andUsernameEqualTo(username); + List memberList = memberMapper.selectByExample(example); + if (!CollectionUtils.isEmpty(memberList)) { + return memberList.get(0); + } + return null; + } + + @Override + public UmsMember register(String username, String password, String telephone, String authCode) { + // TODO: 2018/8/3 对验证码进行验证 + //查询是否已有该用户 + UmsMemberExample example = new UmsMemberExample(); + example.createCriteria().andUsernameEqualTo(username); + example.or(example.createCriteria().andPhoneEqualTo(telephone)); + List umsMembers = memberMapper.selectByExample(example); + if (!CollectionUtils.isEmpty(umsMembers)) { + return null; + } + //没有该用户进行添加操作 + UmsMember umsMember = new UmsMember(); + umsMember.setUsername(username); + umsMember.setPassword(passwordEncoder.encodePassword(password, null)); + umsMember.setCreateTime(new Date()); + umsMember.setStatus(1); + //获取默认会员等级并设置 + UmsMemberLevelExample levelExample = new UmsMemberLevelExample(); + levelExample.createCriteria().andDefaultStatusEqualTo(1); + List memberLevelList = memberLevelMapper.selectByExample(levelExample); + if (!CollectionUtils.isEmpty(memberLevelList)) { + umsMember.setMemberLevelId(memberLevelList.get(0).getId()); + } + memberMapper.insert(umsMember); + umsMember.setPassword(null); + return umsMember; + } + + @Override + public CommonResult login(String username, String password) { + CommonResult result; + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, passwordEncoder.encodePassword(password, null)); + try { + authenticationManager.authenticate(authentication); + SecurityContextHolder.getContext().setAuthentication(authentication); + result = new CommonResult().success("登录成功"); + } catch (AuthenticationException e) { + LOGGER.warn("登录异常:{}", e.getMessage()); + result = new CommonResult().failed("登录异常:"+e.getMessage()); + } + return result; + } + + @Override + public CommonResult generateAuthCode(String telephone) { + return null; + } +}