session短信验证码登录
話不多說,先上代碼:
userservice層代碼:
1、發送驗證碼,使用隨機數生成驗證碼,將驗證碼放到session域中,并且將驗證碼發送給手機(這里我是直接將驗證碼打印到控制臺,你們可以掉第三方的發送驗證碼服務)
@Overridepublic Result setCode(String phone, HttpSession session) {//驗證手機號格式if (RegexUtils.isPhoneInvalid(phone)) {//格式錯誤return Result.fail("手機號格式錯誤");}//格式正確,生成驗證碼,將驗證碼保存到session中String code = RandomUtil.randomNumbers(6);session.setAttribute("code",code);//發送驗證碼System.out.println("驗證碼是: "+code);return Result.ok();}2、用戶登錄,這里先從session域中拿到驗證碼的值并且進行校驗,在從數據庫中查詢手機號如果手機號不存在就新建一個用戶,存在就查詢。將新建或查詢到的用戶放到session域中。
@Overridepublic Result login(LoginFormDTO loginForm, HttpSession session) {String phone = loginForm.getPhone();if (RegexUtils.isPhoneInvalid(phone)) {//格式錯誤return Result.fail("手機號格式錯誤");}Object cacheCode = session.getAttribute("code");String code = loginForm.getCode();if (cacheCode==null || !cacheCode.toString().equals(code)) {return Result.fail("驗證碼輸入錯誤");}User user = query().eq("phone", phone).one();if (user==null) {user = creatUserByphone(phone);}UserDTO userDTO = new UserDTO();userDTO.setNickName(user.getNickName());userDTO.setId(user.getId());userDTO.setIcon(user.getIcon());session.setAttribute("user",userDTO);return Result.ok();}private User creatUserByphone(String phone) {User user = new User();user.setPhone(phone);user.setNickName(USER_NICK_NAME_PREFIX+RandomUtil.randomString(10));save(user);return user;}? ? ? ?
???????? 以上就是userservice層的全部代碼了,然而這樣就結束了嗎?并不是,在訪問一些主流服務前端頁面的時候我們發現有的頁面是只有我們登錄了才可以進行訪問,后端數據也是一樣。所以我們要對一些接口加上攔截器,讓這些接口只有登錄后才可以被訪問。
攔截器代碼
攔截器,實現服務攔截功能,代碼中從請求拿到session,然后在session中拿到user值,不為空則放行。
public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {HttpSession session = request.getSession();Object user = session.getAttribute("user");if (user==null) {return false;}UserHolder.saveUser((UserDTO) user);return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {UserHolder.removeUser();} }spring配置,在代碼中可以添加你想放行的接口,這里我就放行了登錄和獲取驗證碼的接口,你們可以放行一些直接不想攔截的接口。
@Configuration public class MvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor()).excludePathPatterns("/user/login","/user/code");} }在上面攔截器代碼中我們可以發現一個特別的類UserHolder,這是我自己寫的工具類。這里的攔截器雖然獲得了user對象,但攔截器后面的接口可能還需要用到這個user對象,所以我就就使用了這樣一個工具類來,實現對象的傳遞、我們都知道在tomcat中每一個請求都是一個獨立的線程。我們就可以使用Java中的ThreadLocal來實現沒一個線程的user數據隔離,使得每個線程都擁有一個user對象,在需要使用的時候,可以在里面拿。下面是工具類,以及controler怎么拿user對象。
public class UserHolder {private static final ThreadLocal<UserDTO> tl = new ThreadLocal<>();public static void saveUser(UserDTO user){tl.set(user);}public static UserDTO getUser(){return tl.get();}public static void removeUser(){tl.remove();} }//在control中拿到user對象@GetMapping("/me")public Result me(){UserDTO user = UserHolder.getUser();// TODO 獲取當前登錄的用戶并返回return Result.ok(user);}到這今天的代碼就講完了,如果有什么地方寫的不對,希望大家指正。一起進步。
總結
以上是生活随笔為你收集整理的session短信验证码登录的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 滨州智能dcs系统推荐_霍尼韦尔DCS系
- 下一篇: fre740变频器参数_三菱FR-E74