JavaWeb_(视频网址)_二、用户模块1 注册登陆
用户模块
创建用户实体
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String username; private String password; private String email; private String firstName; private String lastName; private String displayNane; //个人首页 private String webUrl; private String phone; //个人描述 private String description; //social Link private String qqLink; private String weixinLink; //封面头像 private String coverImage; //头像 private String headImage; //创建时间 private String createTime;
用户注册流程图
当用户输入手机号后,通过JQery判断用户是否输入正确的手机号,如果正确,则发送验证码,如果错误,则提示用户手机号输入错误
在Controller层中添加用户层UserController,java,用于接收sms请求
@Controller public class UserController { //发送手机验证码 @RequestMapping("/sms") @ResponseBody public String sms(String phone) { System.out.println(phone); return ""; } }
<script src="layer/layer.js"></script> <script type="text/javascript" th:inline="javascript"> //检验短信验证码是否正确 $("#smsInput").blur(function(){ var sms = $("#smsInput").val(); //校验验证码 $.post( //action的地址 [[@{~/judgeSMS}]], //数据 {"sms":sms}, //回调函数 function(data) { if(data.message) { layer.msg("验证码正确!!"); } else { layer.msg("验证码错误!!"); $("#smsInput").val(""); } }, //数据格式 "json" ) }) //发送手机验证码 $("#usernameInput").blur(function(){ //获得手机号 var phone = $("#usernameInput").val(); //判断是否为手机号 if(/^1([358][0-9]|4[579]|66|7[0135678]|9[89])[0-9]{8}$/.test(phone)) { //发送手机验证码 $.post( //action的地址 [[@{~/sms}]], //数据 {"phone":phone}, //回调函数 function(data) { if(data.message) { layer.msg("验证码发送成功~"); } else { layer.msg("该手机号已经被注册~"); } }, //数据格式 "json" ) } else { layer.msg("手机格式有误!!"); } }) </script>
Controller层UserController.java接收到用户发送回来的消息后,使用userService.findUserByUsername(phone)方法查询数据库中手机号是否存在
//发送手机验证码 @RequestMapping("/sms") @ResponseBody public String sms(String phone) { //System.out.println(phone); //判断数据库中是否存在手机号 String json = null; if(userService.findUserByUsername(phone) != null) { //存在,不用发短信 json = "{\"message\":"+false+"}"; }else { //不存在,发送短信 SMS(); json = "{\"message\":"+true+"}"; } return json; }
使用父类CrudRepository.java查询数据库中电话是否重复
@Query(value = "select * from user where username = ?1",nativeQuery = true) User findUserByUsername(String phone);
腾讯云手机发送验证码SMS模块
private void SMS(String telephone,HttpSession session) { // 腾讯云中的数据 int appid = 1400184301; String appkey = "58f61b731363faba756087b9504bff46"; int templateId=275243; String smsSign = "Garyd公众号"; //电话 String phoneNumber = telephone; //验证码 Random r = new Random(); String code = ""; for(int i=0;i<4;i++) { code+=r.nextInt(10); } //放入session域中 session.setAttribute("sms", code); //验证码 String[] params = new String[1]; params[0] = code; System.out.println("验证码为:"+code); //发送验证码模块 SmsSingleSender ssender = new SmsSingleSender(appid, appkey); try { ssender.sendWithParam("86", phoneNumber, templateId, params, smsSign, "", ""); } catch (HTTPException | JSONException | IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
package com.Gary.betobe.controller; import java.io.IOException; import java.util.Random; import javax.servlet.http.HttpSession; import org.json.JSONException; 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.ResponseBody; import com.Gary.betobe.service.UserService; import com.github.qcloudsms.SmsSingleSender; import com.github.qcloudsms.httpclient.HTTPException; @Controller public class UserController { @Autowired private UserService userService; @Autowired private HttpSession session; //发送手机验证码 @RequestMapping("/sms") @ResponseBody public String sms(String phone) { //System.out.println(phone); //判断数据库中是否存在手机号 String json = null; if(userService.findUserByUsername(phone) != null) { //存在,不用发短信 json = "{\"message\":"+false+"}"; }else { //不存在,发送短信 SMS(phone,session); json = "{\"message\":"+true+"}"; } return json; } private void SMS(String telephone,HttpSession session) { // 腾讯云中的数据 int appid = 1400184301; String appkey = "58f61b731363faba756087b9504bff46"; int templateId=275243; String smsSign = "Garyd公众号"; //电话 String phoneNumber = telephone; //验证码 Random r = new Random(); String code = ""; for(int i=0;i<4;i++) { code+=r.nextInt(10); } //放入session域中 session.setAttribute("sms", code); //验证码 String[] params = new String[1]; params[0] = code; System.out.println("验证码为:"+code); //发送验证码模块 SmsSingleSender ssender = new SmsSingleSender(appid, appkey); try { ssender.sendWithParam("86", phoneNumber, templateId, params, smsSign, "", ""); } catch (HTTPException | JSONException | IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
鼠标离焦后,讲验证码发送给手机
login-register登陆注册页面用过javascript去实现离焦后判断用户是否正确输入验证码
//检验短信验证码是否正确 $("#smsInput").blur(function(){ var sms = $("#smsInput").val(); //校验验证码 $.post( //action的地址 [[@{~/judgeSMS}]], //数据 {"sms":sms}, //回调函数 function(data) { if(data.message) { layer.msg("验证码正确!!"); } else { layer.msg("验证码错误!!"); $("#smsInput").val(""); } }, //数据格式 "json" ) })
后台UserController.java中实现对手机验证码的是否正确输入进行判断
//判断手机验证码 @RequestMapping("/judgeSMS") @ResponseBody public String judgeSMS(String sms,HttpSession session) { //sms与Session中的sms对比 String smsInSession = (String)session.getAttribute("sms"); String json = null; if(sms.equals(smsInSession)) { json = "{\"message\":"+true+"}"; } else { json = "{\"message\":"+false+"}"; } return json; }
//检验短信验证码是否正确 $("#smsInput").blur(function(){ var sms = $("#smsInput").val(); //校验验证码 $.post( //action的地址 [[@{~/judgeSMS}]], //数据 {"sms":sms}, //回调函数 function(data) { if(data.message) { layer.msg("验证码正确!!"); } else { layer.msg("验证码错误!!"); $("#smsInput").val(""); } }, //数据格式 "json" ) })
package com.Gary.betobe.controller; import java.io.IOException; import java.util.Random; import javax.servlet.http.HttpSession; import org.json.JSONException; 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.ResponseBody; import com.Gary.betobe.service.UserService; import com.github.qcloudsms.SmsSingleSender; import com.github.qcloudsms.httpclient.HTTPException; @Controller public class UserController { @Autowired private UserService userService; @Autowired private HttpSession session; //判断手机验证码 @RequestMapping("/judgeSMS") @ResponseBody public String judgeSMS(String sms,HttpSession session) { //sms与Session中的sms对比 String smsInSession = (String)session.getAttribute("sms"); String json = null; if(sms.equals(smsInSession)) { json = "{\"message\":"+true+"}"; } else { json = "{\"message\":"+false+"}"; } return json; } //发送手机验证码 @RequestMapping("/sms") @ResponseBody public String sms(String phone) { //System.out.println(phone); //判断数据库中是否存在手机号 String json = null; if(userService.findUserByUsername(phone) != null) { //存在,不用发短信 json = "{\"message\":"+false+"}"; }else { //不存在,发送短信 SMS(phone,session); json = "{\"message\":"+true+"}"; } return json; } private void SMS(String telephone,HttpSession session) { // 腾讯云中的数据 int appid = 1400184301; String appkey = "58f61b731363faba756087b9504bff46"; int templateId=275243; String smsSign = "Garyd公众号"; //电话 String phoneNumber = telephone; //验证码 Random r = new Random(); String code = ""; for(int i=0;i<4;i++) { code+=r.nextInt(10); } //放入session域中 session.setAttribute("sms", code); //验证码 String[] params = new String[1]; params[0] = code; System.out.println("验证码为:"+code); /* //发送验证码模块 SmsSingleSender ssender = new SmsSingleSender(appid, appkey); try { ssender.sendWithParam("86", phoneNumber, templateId, params, smsSign, "", ""); } catch (HTTPException | JSONException | IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } */ } }
实现用户注册功能
注册页面输入手机号信息,邮箱,密码,验证码正确后,当用户点击提交表单后,注册页面将表单传入数据库中。
package com.Gary.betobe.domain; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Lob; @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String username; private String password; private String email; private String firstName; private String lastName; private String displayNane; //个人首页 private String webUrl; private String phone; //个人描述 @Lob //长文本 ->lob对应mysql的数据类型 longtext private String description; //social Link private String qqLink; private String weixinLink; //封面头像 private String coverImage; //头像 private String headImage; //创建时间 private String createTime; //JPA的标准 protected User() { } public User(Long id, String username, String password, String email, String firstName, String lastName, String displayNane, String webUrl, String phone, String description, String qqLink, String weixinLink, String coverImage, String headImage, String createTime) { super(); this.id = id; this.username = username; this.password = password; this.email = email; this.firstName = firstName; this.lastName = lastName; this.displayNane = displayNane; this.webUrl = webUrl; this.phone = phone; this.description = description; this.qqLink = qqLink; this.weixinLink = weixinLink; this.coverImage = coverImage; this.headImage = headImage; this.createTime = createTime; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getDisplayNane() { return displayNane; } public void setDisplayNane(String displayNane) { this.displayNane = displayNane; } public String getWebUrl() { return webUrl; } public void setWebUrl(String webUrl) { this.webUrl = webUrl; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getQqLink() { return qqLink; } public void setQqLink(String qqLink) { this.qqLink = qqLink; } public String getWeixinLink() { return weixinLink; } public void setWeixinLink(String weixinLink) { this.weixinLink = weixinLink; } public String getCoverImage() { return coverImage; } public void setCoverImage(String coverImage) { this.coverImage = coverImage; } public String getHeadImage() { return headImage; } public void setHeadImage(String headImage) { this.headImage = headImage; } public String getCreateTime() { return createTime; } public void setCreateTime(String createTime) { this.createTime = createTime; } }
package com.Gary.betobe.controller; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Random; import javax.servlet.http.HttpSession; import org.json.JSONException; 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.ResponseBody; import com.Gary.betobe.domain.User; import com.Gary.betobe.service.UserService; import com.github.qcloudsms.SmsSingleSender; import com.github.qcloudsms.httpclient.HTTPException; @Controller public class UserController { @Autowired private UserService userService; @Autowired private HttpSession session; //用户注册 @RequestMapping("/register") public String register(User user) { //private String username; //private String password; //private String email; //private String firstName; //private String lastName; //private String displayNane; //个人首页 //private String webUrl; //private String phone; user.setPhone(user.getUsername()); //个人描述 //private String description; //social Link //private String qqLink; //private String weixinLink; //封面头像 //private String coverImage; user.setCoverImage("/images/user/bg/profile-bg.png"); //头像 //private String headImage; Random r = new Random(); user.setHeadImage("/images/user/head/"+r.nextInt(15)+".jpg"); //创建时间 //private String createTime; Date date = new Date(System.currentTimeMillis()); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); user.setCreateTime(format.format(date)); userService.saveUser(user); return "redirect:/loginBetobe"; } //判断手机验证码 @RequestMapping("/judgeSMS") @ResponseBody public String judgeSMS(String sms,HttpSession session) { //sms与Session中的sms对比 String smsInSession = (String)session.getAttribute("sms"); String json = null; if(sms.equals(smsInSession)) { json = "{\"message\":"+true+"}"; } else { json = "{\"message\":"+false+"}"; } return json; } //发送手机验证码 @RequestMapping("/sms") @ResponseBody public String sms(String phone) { //System.out.println(phone); //判断数据库中是否存在手机号 String json = null; if(userService.findUserByUsername(phone) != null) { //存在,不用发短信 json = "{\"message\":"+false+"}"; }else { //不存在,发送短信 SMS(phone,session); json = "{\"message\":"+true+"}"; } return json; } private void SMS(String telephone,HttpSession session) { // 腾讯云中的数据 int appid = 1400184301; String appkey = "58f61b731363faba756087b9504bff46"; int templateId=275243; String smsSign = "Garyd公众号"; //电话 String phoneNumber = telephone; //验证码 Random r = new Random(); String code = ""; for(int i=0;i<4;i++) { code+=r.nextInt(10); } //放入session域中 session.setAttribute("sms", code); //验证码 String[] params = new String[1]; params[0] = code; System.out.println("验证码为:"+code); /* //发送验证码模块 SmsSingleSender ssender = new SmsSingleSender(appid, appkey); try { ssender.sendWithParam("86", phoneNumber, templateId, params, smsSign, "", ""); } catch (HTTPException | JSONException | IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } */ } }
用户登陆功能
用户登陆流程图
防止页面在未登录的情况下访问不到资源,在SecurityConfig.java中通过http.authorizeRequests().antMatchers开放资源
//做拦截 @Override protected void configure(HttpSecurity http) throws Exception { //请求授权 http.formLogin() //自己登陆页面 .loginPage("/loginBetobe") //自己的表单登陆的URL .loginProcessingUrl("/loginPage") .and() .authorizeRequests() .antMatchers("/loginRegister","/sms","/judgeSMS","/register","/loginBetobe", "/scss/**","/layerslider/**","/layer/**","/js/**","/images/**","/fonts/**","/dist/**","/css/**","/api/**","/bower_components/**" ).permitAll() //所有请求 .anyRequest() //都需要我们身份认证 .authenticated().and() //跨站请求伪造和防护 .csrf().disable(); }
用户登陆模块,在SocialUserServiceimpl.java中判断登陆的用户在数据库中是否存在
@Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // System.out.println(username); User user = userService.findUserByUsername(username); // 查找是否存在该用户 if (user == null) { // 不存在,UsernameNotFoundException throw new UsernameNotFoundException(""); } // 存在,给我们SpringSecurity用户名及密码,权限 return new SocialUser(user.getUsername(), passwordEncoder.encode(user.getPassword()), true, true, true, true, AuthorityUtils.commaSeparatedStringToAuthorityList("USER")); }
package com.Gary.betobe.service.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Component; import org.springframework.social.security.SocialUser; import org.springframework.social.security.SocialUserDetails; import org.springframework.social.security.SocialUserDetailsService; import com.Gary.betobe.domain.User; import com.Gary.betobe.service.UserService; @Component public class SocialUserServiceimpl implements UserDetailsService { @Autowired private UserService userService; @Autowired private PasswordEncoder passwordEncoder; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // System.out.println(username); User user = userService.findUserByUsername(username); // 查找是否存在该用户 if (user == null) { // 不存在,UsernameNotFoundException throw new UsernameNotFoundException(""); } // 存在,给我们SpringSecurity用户名及密码,权限 return new SocialUser(user.getUsername(), passwordEncoder.encode(user.getPassword()), true, true, true, true, AuthorityUtils.commaSeparatedStringToAuthorityList("USER")); } }
用户登陆成功or失败处理
LoginSuccessHandler.java处理用户登陆成功
@Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException { // TODO Auto-generated method stub //成功,,跳转到首页 response.sendRedirect("/index"); //super.onAuthenticationSuccess(request, response, authentication); }
LoginFailureHandler.java处理用户登陆失败
@Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { // TODO Auto-generated method stub //在request域中放置错误信息 request.setAttribute("error", "Error in username or password"); //转发到loginBetobe request.getRequestDispatcher("/loginBetobe").forward(request, response); //super.onAuthenticationFailure(request, response, exception); }
在SecurityConfig.java中添加两个handler
@Autowired private LoginSuccessHandler loginSuccessHandler; @Autowired private LoginFailureHandler loginFailureHandler;
实现登陆失败提示的显示
当登陆成功时,跳转到index.html首页面
当登陆失败时,在login.html页面中添加javascript代码,使得刷新页面后,显示Error的信息
<script type="text/javascript" th:inline="javascript"> //当页面加载完成的时候会调用 window.onload = function error() { //如果错误的信息不为空 if([[${error}]] != null) { //显示Error的信息 $("#error").html([[${error}]]); $("#errorMessage").show(); } } </script>
记住我功能
实现记住我功能流程图
记住我的checkbox
<div class="checkbox"> <input id="remember" type="checkbox" name="remember-me" value="true"> <label class="customLabel" for="remember">Remember me</label> </div>
在SecurityConfig.java中实现保存浏览器中的Token
//做拦截 @Override protected void configure(HttpSecurity http) throws Exception { //请求授权 http.formLogin() //自己登陆页面 .loginPage("/loginBetobe") //自己的表单登陆的URL .loginProcessingUrl("/loginPage") //登陆成功的处理 .successHandler(loginSuccessHandler) //登陆失败的处理 .failureHandler(loginFailureHandler) //记住我 .and() .rememberMe() .tokenRepository(persistentTokenRepository()) //配置Token过期秒数 .tokenValiditySeconds(60000) .userDetailsService(userDetailsService) .and() .authorizeRequests() .antMatchers("/loginRegister","/sms","/judgeSMS","/register","/loginBetobe", "/scss/**","/layerslider/**","/layer/**","/js/**","/images/**","/fonts/**","/dist/**","/css/**","/api/**","/bower_components/**" ).permitAll() //所有请求 .anyRequest() //都需要我们身份认证 .authenticated().and() //跨站请求伪造和防护 .csrf().disable(); }
package com.Gary.betobe.config; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; 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.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl; import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository; import com.Gary.betobe.handler.LoginFailureHandler; import com.Gary.betobe.handler.LoginSuccessHandler; @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter{ //告诉SpringSecurity我们密码使用什么加密的 @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Autowired private LoginSuccessHandler loginSuccessHandler; @Autowired private LoginFailureHandler loginFailureHandler; @Autowired private DataSource dataSource; @Autowired private UserDetailsService userDetailsService; public PersistentTokenRepository persistentTokenRepository() { JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl(); tokenRepository.setDataSource(dataSource); return tokenRepository; } //做拦截 @Override protected void configure(HttpSecurity http) throws Exception { //请求授权 http.formLogin() //自己登陆页面 .loginPage("/loginBetobe") //自己的表单登陆的URL .loginProcessingUrl("/loginPage") //登陆成功的处理 .successHandler(loginSuccessHandler) //登陆失败的处理 .failureHandler(loginFailureHandler) //记住我 .and() .rememberMe() .tokenRepository(persistentTokenRepository()) //配置Token过期秒数 .tokenValiditySeconds(60000) .userDetailsService(userDetailsService) .and() .authorizeRequests() .antMatchers("/loginRegister","/sms","/judgeSMS","/register","/loginBetobe", "/scss/**","/layerslider/**","/layer/**","/js/**","/images/**","/fonts/**","/dist/**","/css/**","/api/**","/bower_components/**" ).permitAll() //所有请求 .anyRequest() //都需要我们身份认证 .authenticated().and() //跨站请求伪造和防护 .csrf().disable(); } }
将记住我的功能中的Token配置秒速添加到application.properties中
#Thymeleaf 编码 spring.thymeleaf.encoding=UTF-8 #热部署静态文件 spring.thymeleaf.cache=false #使用HTML5标准 spring.thymeleaf.mode=HTML5 #使用H2控制台 spring.h2.console.enabled=true #DataSource spring.datasource.url=jdbc:mysql:///betobe?serverTimezone=UTC&characterEncoding=utf-8 spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver #JPA spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=update #扩大Sesison作用范围 spring.jpa.open-in-view=true #Token过期的时间 gary.security.rememberMeSecondes = 100000
package com.Gary.betobe.config; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.security.SecurityProperties; import org.springframework.context.annotation.Bean; 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.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl; import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository; import com.Gary.betobe.handler.LoginFailureHandler; import com.Gary.betobe.handler.LoginSuccessHandler; import com.Gary.betobe.properties.SecurityProperites; @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter{ //告诉SpringSecurity我们密码使用什么加密的 @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Autowired private LoginSuccessHandler loginSuccessHandler; @Autowired private LoginFailureHandler loginFailureHandler; @Autowired private DataSource dataSource; @Autowired private UserDetailsService userDetailsService; @Autowired private SecurityProperites securityProperties; public PersistentTokenRepository persistentTokenRepository() { JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl(); tokenRepository.setDataSource(dataSource); return tokenRepository; } //做拦截 @Override protected void configure(HttpSecurity http) throws Exception { //请求授权 http.formLogin() //自己登陆页面 .loginPage("/loginBetobe") //自己的表单登陆的URL .loginProcessingUrl("/loginPage") //登陆成功的处理 .successHandler(loginSuccessHandler) //登陆失败的处理 .failureHandler(loginFailureHandler) //记住我 .and() .rememberMe() .tokenRepository(persistentTokenRepository()) //配置Token过期秒数 .tokenValiditySeconds(securityProperties.getRememberMeSeconds()) .userDetailsService(userDetailsService) .and() .authorizeRequests() .antMatchers("/loginRegister","/sms","/judgeSMS","/register","/loginBetobe", "/scss/**","/layerslider/**","/layer/**","/js/**","/images/**","/fonts/**","/dist/**","/css/**","/api/**","/bower_components/**" ).permitAll() //所有请求 .anyRequest() //都需要我们身份认证 .authenticated().and() //跨站请求伪造和防护 .csrf().disable(); } }
package com.Gary.betobe.properties; import org.springframework.boot.autoconfigure.security.SecurityProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Configuration; @Configuration //让我们的配置生效 @EnableConfigurationProperties(SecurityProperties.class) public class GarySecurityConfig { }
package com.Gary.betobe.properties; import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(prefix = "gary.security") public class SecurityProperites { private int rememberMeSeconds = 36000; public int getRememberMeSeconds() { return rememberMeSeconds; } public void setRememberMeSeconds(int rememberMeSeconds) { this.rememberMeSeconds = rememberMeSeconds; } }
忘记密码
用户忘记密码时,找回密码流程图
用户忘记密码页面logon-forgot-pass.html
用户忘记密码表单请求
<form th:action="@{~/forgotPassword}" method="post" data-abide novalidate> <div id="errorMessage" data-abide-error class="alert callout" style="display: none;"> <p> <i class="fa fa-exclamation-triangle"></i> <span id="error">There are some errors in your form.</span> </p> </div> <div class="input-group"> <span class="input-group-label"> <i class="fa fa-phone"></i> </span> <input th:value="${phone}" type="text" name="phone" placeholder="Enter your phone" required> <span class="form-error">phone is required</span> </div> <div class="input-group"> <span class="input-group-label"> <i class="fa fa-envelope"></i> </span> <input th:value="${email}" type="email" name="email" placeholder="Enter your email" required> <span class="form-error">email is required</span> </div> <button class="button expanded" type="submit" name="submit">reset Now</button> </form>
为了让用户获得良好体验,当用户输入正确电话,错误邮箱时,忘记密码页面保存用户输入的正确电话;当用户输入错误电话,正确邮箱时,忘记密码页面保存用户输入的正确邮箱。
//忘记密码 @RequestMapping("/forgotPassword") public String forgotPassword(String phone,String email,Model model) { System.out.println("123123123"); //根据Phone找到用户 User user=userService.findUserByPhone(phone); System.err.println(phone); //找到了 if(user != null) { //判断邮箱是否正确 if(user.getEmail().equals(email)) { //正确 //发送邮箱重置密码 //TODO System.out.println("发送邮箱"); } else { //不正确 //邮箱错误:phone就不用重新输入 model.addAttribute("error", "Error in email"); model.addAttribute("phone", phone); System.out.println("邮箱错误"); return "login-forgot-pass.html"; } } //没找到 else { //phone错误:邮箱就不用重新输入 model.addAttribute("error", "Error in phone"); model.addAttribute("email", email); return "login-forgot-pass.html"; } return "redirect:/loginBetobe"; }
<!doctype html> <html class="no-js" lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"> <head> <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content="ie=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>BeTube video</title> <link rel="stylesheet" href="css/app.css"> <link rel="stylesheet" href="css/theme.css"> <link rel="stylesheet" href="css/font-awesome.min.css"> <link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700,800' rel='stylesheet' type='text/css'> <link rel="stylesheet" type="text/css" href="layerslider/css/layerslider.css"> <link rel="stylesheet" href="css/owl.carousel.min.css"> <link rel="stylesheet" href="css/owl.theme.default.min.css"> <link rel="stylesheet" href="css/jquery.kyco.easyshare.css"> <link rel="stylesheet" href="css/responsive.css"> </head> <body> <div class="off-canvas-wrapper"> <div class="off-canvas-wrapper-inner" data-off-canvas-wrapper> <!--header--> <div th:replace="~{fragments/header::header}"></div> <!-- End Header --> <!--breadcrumbs--> <section id="breadcrumb"> <div class="row"> <div class="large-12 columns"> <nav aria-label="You are here:" role="navigation"> <ul class="breadcrumbs"> <li> <i class="fa fa-home"></i> <a href="#">Home</a> </li> <li> <span class="show-for-sr">Current: </span> Login </li> </ul> </nav> </div> </div> </section> <!--end breadcrumbs--> <!-- registration --> <section class="registration"> <div class="row secBg"> <div class="large-12 columns"> <div class="login-register-content"> <div class="row collapse borderBottom"> <div class="medium-6 large-centered medium-centered"> <div class="page-heading text-center"> <h3>Forgot Password</h3> <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s</p> </div> </div> </div> <div class="row" data-equalizer data-equalize-on="medium" id="test-eq"> <div class="large-4 medium-6 large-centered medium-centered columns"> <div class="register-form"> <h5 class="text-center">Enter Email</h5> <form th:action="@{~/forgotPassword}" method="post" data-abide novalidate> <div id="errorMessage" data-abide-error class="alert callout" style="display: none;"> <p> <i class="fa fa-exclamation-triangle"></i> <span id="error">There are some errors in your form.</span> </p> </div> <div class="input-group"> <span class="input-group-label"> <i class="fa fa-phone"></i> </span> <input th:value="${phone}" type="text" name="phone" placeholder="Enter your phone" required> <span class="form-error">phone is required</span> </div> <div class="input-group"> <span class="input-group-label"> <i class="fa fa-envelope"></i> </span> <input th:value="${email}" type="email" name="email" placeholder="Enter your email" required> <span class="form-error">email is required</span> </div> <button class="button expanded" type="submit" name="submit">reset Now</button> </form> </div> </div> </div> </div> </div> </div> </section> <!-- footer --> <div th:replace="~{fragments/footer::footer}"></div> <!--end off canvas content--> </div> <!--end off canvas wrapper inner--> </div> <!--end off canvas wrapper--> <script src="js/jquery.js"></script> <script type="text/javascript" th:inline="javascript"> //当页面加载完成的时候会调用 window.onload = function error() { //如果错误的信息不为空 if([[${error}]] != null) { //显示Error的信息 $("#error").html([[${error}]]); $("#errorMessage").show(); } } </script> <!-- script files --> <script src="bower_components/jquery/dist/jquery.js"></script> <script src="bower_components/what-input/what-input.js"></script> <script src="bower_components/foundation-sites/dist/foundation.js"></script> <script src="js/jquery.showmore.src.js" type="text/javascript"></script> <script src="js/app.js"></script> <script src="layerslider/js/greensock.js" type="text/javascript"></script> <!-- LayerSlider script files --> <script src="layerslider/js/layerslider.transitions.js" type="text/javascript"></script> <script src="layerslider/js/layerslider.kreaturamedia.jquery.js" type="text/javascript"></script> <script src="js/owl.carousel.min.js"></script> <script src="js/inewsticker.js" type="text/javascript"></script> <script src="js/jquery.kyco.easyshare.js" type="text/javascript"></script> </body> </html>
package com.Gary.betobe.controller; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Random; import javax.servlet.http.HttpSession; import org.json.JSONException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.Gary.betobe.domain.User; import com.Gary.betobe.service.UserService; import com.github.qcloudsms.SmsSingleSender; import com.github.qcloudsms.httpclient.HTTPException; @Controller public class UserController { @Autowired private UserService userService; @Autowired private HttpSession session; //忘记密码 @RequestMapping("/forgotPassword") public String forgotPassword(String phone,String email,Model model) { System.out.println("123123123"); //根据Phone找到用户 User user=userService.findUserByPhone(phone); System.err.println(phone); //找到了 if(user != null) { //判断邮箱是否正确 if(user.getEmail().equals(email)) { //正确 //发送邮箱重置密码 //TODO System.out.println("发送邮箱"); } else { //不正确 //邮箱错误:phone就不用重新输入 model.addAttribute("error", "Error in email"); model.addAttribute("phone", phone); System.out.println("邮箱错误"); return "login-forgot-pass.html"; } } //没找到 else { //phone错误:邮箱就不用重新输入 model.addAttribute("error", "Error in phone"); model.addAttribute("email", email); return "login-forgot-pass.html"; } return "redirect:/loginBetobe"; } //用户注册 @RequestMapping("/register") public String register(User user) { //private String username; //private String password; //private String email; //private String firstName; //private String lastName; //private String displayNane; //个人首页 //private String webUrl; //private String phone; user.setPhone(user.getUsername()); //个人描述 //private String description; //social Link //private String qqLink; //private String weixinLink; //封面头像 //private String coverImage; user.setCoverImage("/images/user/bg/profile-bg.png"); //头像 //private String headImage; Random r = new Random(); user.setHeadImage("/images/user/head/"+r.nextInt(15)+".jpg"); //创建时间 //private String createTime; Date date = new Date(System.currentTimeMillis()); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); user.setCreateTime(format.format(date)); userService.saveUser(user); return "redirect:/loginBetobe"; } //判断手机验证码 @RequestMapping("/judgeSMS") @ResponseBody public String judgeSMS(String sms,HttpSession session) { //sms与Session中的sms对比 String smsInSession = (String)session.getAttribute("sms"); String json = null; if(sms.equals(smsInSession)) { json = "{\"message\":"+true+"}"; } else { json = "{\"message\":"+false+"}"; } return json; } //发送手机验证码 @RequestMapping("/sms") @ResponseBody public String sms(String phone) { //System.out.println(phone); //判断数据库中是否存在手机号 String json = null; if(userService.findUserByUsername(phone) != null) { //存在,不用发短信 json = "{\"message\":"+false+"}"; }else { //不存在,发送短信 SMS(phone,session); json = "{\"message\":"+true+"}"; } return json; } private void SMS(String telephone,HttpSession session) { // 腾讯云中的数据 int appid = 1400184301; String appkey = "58f61b731363faba756087b9504bff46"; int templateId=275243; String smsSign = "Garyd公众号"; //电话 String phoneNumber = telephone; //验证码 Random r = new Random(); String code = ""; for(int i=0;i<4;i++) { code+=r.nextInt(10); } //放入session域中 session.setAttribute("sms", code); //验证码 String[] params = new String[1]; params[0] = code; System.out.println("验证码为:"+code); //发送验证码模块 /* SmsSingleSender ssender = new SmsSingleSender(appid, appkey); try { ssender.sendWithParam("86", phoneNumber, templateId, params, smsSign, "", ""); } catch (HTTPException | JSONException | IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } */ } }
实现发送Email的工具类SendEmailManager.class
SendEmailManager.java为发送Email的工具类,异步发送,线程发送邮箱
登陆自己发送邮箱的账号,在账户设置中,开启POP3服务
完成发送邮件的工具类SendEmailManager.java
发送邮箱sendMail()方法
//发送邮箱 private void sendMail(String mailAdr, String subject, String content) throws Exception { //邮箱工厂 MailSSLSocketFactory sf = new MailSSLSocketFactory(); //设置主机 sf.setTrustAllHosts(true); //设置参数 final Properties props = new Properties(); //表示SMTP发送邮件,需要进行身份认证 //协议 props.put("mail.transport.protocol", "smtp"); //授权 props.put("mail.smtp.auth", "true"); //QQ协议 props.put("mail.smtp.host", "smtp.qq.com"); //smpt登陆的账号、密码 props.setProperty("mail.debug", "true"); props.put("mail.user", "1138720556@qq.com"); props.put("mail.password", "hvibehsyuyfpgibh"); //特别需要注意,要将ssl协议设置为true,否则会报503错误 props.put("mail.smtp.ssl.enable", "true"); props.put("mail.smtp.ssl.socketFactory", sf); //设置发送者 Authenticator authenticator = new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { //用户名 , 密码 return 出来 String userName = props.getProperty("mail.user"); String password = props.getProperty("mail.password"); return new PasswordAuthentication(userName,password); } }; //使用环境属性和授权信息,创建邮件绘画 Session mailSession = Session.getInstance(props,authenticator); //创建邮件信息 MimeMessage message = new MimeMessage(mailSession); //设置发件人 InternetAddress form = new InternetAddress(props.getProperty("mail.user")); message.setFrom(form); //设置收件人 InternetAddress to = new InternetAddress(mailAdr); message.setRecipient(RecipientType.TO, to); //设置邮箱标题 message.setSubject(subject); //设置邮箱的内容体 message.setContent(content,"text/html;charset=UTF-8"); //发送邮箱 Transport.send(message); }
package com.Gary.betobe.utils; import java.security.GeneralSecurityException; import java.util.Properties; import javax.mail.Authenticator; import javax.mail.Message.RecipientType; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import com.sun.mail.util.MailSSLSocketFactory; //发送Email的工具类,异步发送,线程发送 public class SendEmailManager extends Thread{ //谁发送的 //发送的地址 private String mailAdr; //发送的内容 private String content; //发送的标题 private String subject; public SendEmailManager(String mailAdr,String subject,String content) { this.mailAdr = mailAdr; this.content = content; this.subject = subject; } @Override public void run() { // TODO Auto-generated method stub super.run(); try { sendMail(mailAdr,subject,content); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } //发送邮箱 private void sendMail(String mailAdr, String subject, String content) throws Exception { //邮箱工厂 MailSSLSocketFactory sf = new MailSSLSocketFactory(); //设置主机 sf.setTrustAllHosts(true); //设置参数 final Properties props = new Properties(); //表示SMTP发送邮件,需要进行身份认证 //协议 props.put("mail.transport.protocol", "smtp"); //授权 props.put("mail.smtp.auth", "true"); //QQ协议 props.put("mail.smtp.host", "smtp.qq.com"); //smpt登陆的账号、密码 props.setProperty("mail.debug", "true"); props.put("mail.user", "1138720556@qq.com"); props.put("mail.password", "hvibehsyuyfpgibh"); //特别需要注意,要将ssl协议设置为true,否则会报503错误 props.put("mail.smtp.ssl.enable", "true"); props.put("mail.smtp.ssl.socketFactory", sf); //设置发送者 Authenticator authenticator = new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { //用户名 , 密码 return 出来 String userName = props.getProperty("mail.user"); String password = props.getProperty("mail.password"); return new PasswordAuthentication(userName,password); } }; //使用环境属性和授权信息,创建邮件绘画 Session mailSession = Session.getInstance(props,authenticator); //创建邮件信息 MimeMessage message = new MimeMessage(mailSession); //设置发件人 InternetAddress form = new InternetAddress(props.getProperty("mail.user")); message.setFrom(form); //设置收件人 InternetAddress to = new InternetAddress(mailAdr); message.setRecipient(RecipientType.TO, to); //设置邮箱标题 message.setSubject(subject); //设置邮箱的内容体 message.setContent(content,"text/html;charset=UTF-8"); //发送邮箱 Transport.send(message); } }
当用户发送邮箱生成随机六位数字密码后,在数据库中进行用户密码的同步
package com.Gary.betobe.utils; import java.security.GeneralSecurityException; import java.util.Properties; import javax.mail.Authenticator; import javax.mail.Message.RecipientType; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import com.sun.mail.util.MailSSLSocketFactory; //发送Email的工具类,异步发送,线程发送 public class SendEmailManager extends Thread{ //谁发送的 //发送的地址 private String mailAdr; //发送的内容 private String content; //发送的标题 private String subject; public SendEmailManager(String mailAdr,String subject,String content) { this.mailAdr = mailAdr; this.content = content; this.subject = subject; } @Override public void run() { // TODO Auto-generated method stub super.run(); try { sendMail(mailAdr,subject,content); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } //发送邮箱 private void sendMail(String mailAdr, String subject, String content) throws Exception { //邮箱工厂 MailSSLSocketFactory sf = new MailSSLSocketFactory(); //设置主机 sf.setTrustAllHosts(true); //设置参数 final Properties props = new Properties(); //表示SMTP发送邮件,需要进行身份认证 //协议 props.put("mail.transport.protocol", "smtp"); //授权 props.put("mail.smtp.auth", "true"); //QQ协议 props.put("mail.smtp.host", "smtp.qq.com"); //smpt登陆的账号、密码 props.setProperty("mail.debug", "true"); props.put("mail.user", "1138720556@qq.com"); props.put("mail.password", "hvibehsyuyfpgibh"); //特别需要注意,要将ssl协议设置为true,否则会报503错误 props.put("mail.smtp.ssl.enable", "true"); props.put("mail.smtp.ssl.socketFactory", sf); //设置发送者 Authenticator authenticator = new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { //用户名 , 密码 return 出来 String userName = props.getProperty("mail.user"); String password = props.getProperty("mail.password"); return new PasswordAuthentication(userName,password); } }; //使用环境属性和授权信息,创建邮件绘画 Session mailSession = Session.getInstance(props,authenticator); //创建邮件信息 MimeMessage message = new MimeMessage(mailSession); //设置发件人 InternetAddress form = new InternetAddress(props.getProperty("mail.user")); message.setFrom(form); //设置收件人 InternetAddress to = new InternetAddress(mailAdr); message.setRecipient(RecipientType.TO, to); //设置邮箱标题 message.setSubject(subject); //设置邮箱的内容体 message.setContent(content,"text/html;charset=UTF-8"); //发送邮箱 Transport.send(message); } }
package com.Gary.betobe.controller; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Random; import javax.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.Gary.betobe.domain.User; import com.Gary.betobe.service.UserService; import com.Gary.betobe.utils.SendEmailManager; import com.github.qcloudsms.SmsSingleSender; import com.github.qcloudsms.httpclient.HTTPException; @Controller public class UserController { @Autowired private UserService userService; @Autowired private HttpSession session; //忘记密码 @RequestMapping("/forgotPassword") public String forgotPassword(String phone,String email,Model model) { System.out.println("123123123"); //根据Phone找到用户 User user=userService.findUserByPhone(phone); System.err.println(phone); //找到了 if(user != null) { //判断邮箱是否正确 if(user.getEmail().equals(email)) { Random r = new Random(); String password = ""; //正确 if(user.getEmail().equals(email)) { for(int i=0;i<6;i++) { password += r.nextInt(10); } } //发送邮箱重置密码 SendEmailManager d = new SendEmailManager(email,"Gary-毕设-密码重置","你好:<br/><br/><p>重置密码为:</p><br/><p style='color:red'>"+password+"</p>"); d.start(); //同步到数据库 System.out.println("发送邮箱"); //同步到数据库 userService.changeUserPasswordByPhoneAndEmail(phone,email,password); } else { //不正确 //邮箱错误:phone就不用重新输入 model.addAttribute("error", "Error in email"); model.addAttribute("phone", phone); System.out.println("邮箱错误"); return "login-forgot-pass.html"; } } //没找到 else { //phone错误:邮箱就不用重新输入 model.addAttribute("error", "Error in phone"); model.addAttribute("email", email); return "login-forgot-pass.html"; } return "redirect:/loginBetobe"; } //用户注册 @RequestMapping("/register") public String register(User user) { //private String username; //private String password; //private String email; //private String firstName; //private String lastName; //private String displayNane; //个人首页 //private String webUrl; //private String phone; user.setPhone(user.getUsername()); //个人描述 //private String description; //social Link //private String qqLink; //private String weixinLink; //封面头像 //private String coverImage; user.setCoverImage("/images/user/bg/profile-bg.png"); //头像 //private String headImage; Random r = new Random(); user.setHeadImage("/images/user/head/"+r.nextInt(15)+".jpg"); //创建时间 //private String createTime; Date date = new Date(System.currentTimeMillis()); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); user.setCreateTime(format.format(date)); userService.saveUser(user); return "redirect:/loginBetobe"; } //判断手机验证码 @RequestMapping("/judgeSMS") @ResponseBody public String judgeSMS(String sms,HttpSession session) { //sms与Session中的sms对比 String smsInSession = (String)session.getAttribute("sms"); String json = null; if(sms.equals(smsInSession)) { json = "{\"message\":"+true+"}"; } else { json = "{\"message\":"+false+"}"; } return json; } //发送手机验证码 @RequestMapping("/sms") @ResponseBody public String sms(String phone) { //System.out.println(phone); //判断数据库中是否存在手机号 String json = null; if(userService.findUserByUsername(phone) != null) { //存在,不用发短信 json = "{\"message\":"+false+"}"; }else { //不存在,发送短信 SMS(phone,session); json = "{\"message\":"+true+"}"; } return json; } private void SMS(String telephone,HttpSession session) { // 腾讯云中的数据 int appid = 1400184301; String appkey = "58f61b731363faba756087b9504bff46"; int templateId=275243; String smsSign = "Garyd公众号"; //电话 String phoneNumber = telephone; //验证码 Random r = new Random(); String code = ""; for(int i=0;i<4;i++) { code+=r.nextInt(10); } //放入session域中 session.setAttribute("sms", code); //验证码 String[] params = new String[1]; params[0] = code; System.out.println("验证码为:"+code); //发送验证码模块 /* SmsSingleSender ssender = new SmsSingleSender(appid, appkey); try { ssender.sendWithParam("86", phoneNumber, templateId, params, smsSign, "", ""); } catch (HTTPException | JSONException | IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } */ } }
package com.Gary.betobe.service; import org.springframework.stereotype.Service; import com.Gary.betobe.domain.User; @Service public interface UserService { User findUserByUsername(String phone); void saveUser(User user); User findUserByPhone(String phone); void changeUserPasswordByPhoneAndEmail(String phone, String email, String password); }
package com.Gary.betobe.service.impl; import javax.transaction.Transactional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.Gary.betobe.domain.User; import com.Gary.betobe.repository.UserRepository; import com.Gary.betobe.service.UserService; @Component public class UserServiceImpl implements UserService{ @Autowired private UserRepository userRepository; @Override public User findUserByUsername(String phone) { User user = userRepository.findUserByUsername(phone); return user; } @Override public void saveUser(User user) { userRepository.save(user); } @Override public User findUserByPhone(String phone) { User user = userRepository.findUserByPhone(phone); return user; } @Override @Transactional public void changeUserPasswordByPhoneAndEmail(String phone, String email,String password) { userRepository.changeUserPasswordByPhoneAndEmail(phone,email,password); } }
package com.Gary.betobe.repository; import org.springframework.data.repository.CrudRepository; import com.Gary.betobe.domain.User; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; public interface UserRepository extends CrudRepository<User,Long>{ @Query(value = "select * from user where username = ?1",nativeQuery = true) User findUserByUsername(String phone); @Query(value = "select * from user where phone = ?1",nativeQuery = true) User findUserByPhone(String phone); @Query(value = "update user set password = ?3 where phone = ?1 and email = ?2",nativeQuery = true) @Modifying void changeUserPasswordByPhoneAndEmail(String phone, String email, String password); }