当前位置: 首页 > news >正文

自己买服务器做视频网站赣州seo外包

自己买服务器做视频网站,赣州seo外包,做电影数据的网站,武汉住房和城乡建设厅网站项目介绍 导入黑马点评项目 项目架构 基于Session实现登录 基本流程 实现发送短信验证码功能 controller层中 /*** 发送手机验证码*/PostMapping("code")public Result sendCode(RequestParam("phone") String phone, HttpSession session) {// 发送短信…

项目介绍

导入黑马点评项目

项目架构

 

 

基于Session实现登录

基本流程

实现发送短信验证码功能

 controller层中

    /*** 发送手机验证码*/@PostMapping("code")public Result sendCode(@RequestParam("phone") String phone, HttpSession session) {//  发送短信验证码并保存验证码return userService.sendCode(phone,session);}

Service层中

真的发送的话要接入阿里云或腾讯云的短信发送功能,这里假装发送成功。

@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {@Overridepublic Result sendCode(String phone, HttpSession session) {//1.校验手机号if(RegexUtils.isPhoneInvalid(phone)){//2.如果不符合,返回错误信息return Result.fail("手机号格式错误!");}//3.符合,生成验证码String code = RandomUtil.randomNumbers(6);//4.保存验证码session.setAttribute("code",code);//5.发送验证码log.debug("发送短信验证码成功,验证码:{}",code);return Result.ok();}
}

再次点击发送就可以看见如下:

 

实现验证码登录和注册功能

Controller层中

    /*** 登录功能* @param loginForm 登录参数,包含手机号、验证码;或者手机号、密码*/@PostMapping("/login")public Result login(@RequestBody LoginFormDTO loginForm, HttpSession session){// 实现登录功能return userService.login(loginForm,session);}

Service层中

    @Overridepublic Result login(LoginFormDTO loginForm, HttpSession session) {//1.验证手机号String phone=loginForm.getPhone();if(RegexUtils.isPhoneInvalid(phone)){//1.1不符合,返回报错return Result.fail("手机号格式错误!");}//2.校验验证码Object cacheCode = session.getAttribute("code");String code = loginForm.getCode();if(cacheCode==null||!cacheCode.toString().equals(code)){//3.不一致,报错return Result.fail("验证码错误");}//4.一致,根据手机号查询用户 select * from tb_user where phone=?User user = query().eq("phone", phone).one();//5.判断用户是否存在if(user==null){//6.不存在,创建新用户并保存user=   createUserWithPhone(phone);}//7.存在,保存用户信息到session中session.setAttribute("user",user);return Result.ok();}private User createUserWithPhone(String phone) {//1.创建用户User user=new User();user.setPhone(phone);user.setNickName(USER_NICK_NAME_PREFIX+RandomUtil.randomString(10));//2.保存save(user);return user;}

这里的session之所以能够获取到发送验证码请求时存入的验证码是因为这是在同一个会话当中,session会被返回给前端,下一次请求也会携带同一个session过来。所以才有之前保存的信息在里面。

实现登录校验拦截器

 

 接口多了之后就要拦截器进行统一校验,然后为了传递用户信息给后序的业务,需要将用户信息存入Threadlocal里面的.Threadlocal是每个请求线程的一个独立保存空间。

在拦截器的最后一个方法中,清空thread local的信息,第一可以做到退出登录,第二可以防止内存泄露

新建一个拦截器

public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//1.获取sessionHttpSession session = request.getSession();//2.获取session中的用户Object user = session.getAttribute("user");//3.判断用户是否存在if(user==null){//4.不存在,拦截response.setStatus(401);return false;}//5.存在,保存用户信息到ThreadLocalUserHolder.saveUser((UserDTO) user);//6.放行return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {//移除用户UserHolder.removeUser();}
}

 新建配置项

将上面的拦截器投入使用,并且指定不拦截的请求。

@Configuration
public class MvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor()).excludePathPatterns("/shop/**","/shop-type/**","/upload/**","/blog/hot","/user/code" ,"/user/login");}
}

登录校验接口

    @GetMapping("/me")public Result me(){// 获取当前登录的用户并返回UserDTO user= UserHolder.getUser();return Result.ok(user);}

隐藏用户敏感信息

在前面代码里返回给前端的是用户完整信息,这是不合理的,所以改成如下。

在session存的时候就只存部分信息。然后上面登录校验逻辑因为黑马资料的问题已经是隐藏之后的了的,所以只改这里一个地方即可。

    @Overridepublic Result login(LoginFormDTO loginForm, HttpSession session) {........//7.存在,保存用户信息到session中session.setAttribute("user", BeanUtil.copyProperties(user, UserDTO.class));return Result.ok();}

集群的session共享问题

使用Redis解决Session共享问题。 

基于Redis实现共享session登录

业务流程

基于redis实现短信登录

发送短信验证码部分的代码修改:

生成验证码之后将验证码存入Redis

    @Resourceprivate StringRedisTemplate stringRedisTemplate;@Overridepublic Result sendCode(String phone, HttpSession session) {//1.校验手机号...//3.符合,生成验证码...//4.保存验证码到RedisstringRedisTemplate.opsForValue().set("login:code:"+phone,code,2, TimeUnit.MINUTES);//5.发送验证码...}

短信验证码登录,注册功能部分的代码修改:

    @Overridepublic Result login(LoginFormDTO loginForm, HttpSession session) {//1.验证手机号...//  2.从redis获取 校验验证码String cacheCode = stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY+phone);...//4.一致,根据手机号查询用户 select * from tb_user where phone=?...//5.判断用户是否存在...//7.存在,保存用户信息到Redis中//7.1.随机生成token,作为登录令牌String token = UUID.randomUUID().toString(true);//7.2将User对象转为Hash存储UserDTO userDTO=BeanUtil.copyProperties(user, UserDTO.class);Map<String, Object> userMap = BeanUtil.beanToMap(userDTO);//7.3存储String tokenKey="login::token:"+token;stringRedisTemplate.opsForHash().putAll(tokenKey,userMap);//7.4设置token有效期stringRedisTemplate.expire(tokenKey,30,TimeUnit.MINUTES);//8.返回tokenreturn Result.ok(token);}

登录拦截器代码修改


public class LoginInterceptor implements HandlerInterceptor {private StringRedisTemplate stringRedisTemplate;public LoginInterceptor(StringRedisTemplate stringRedisTemplate) {this.stringRedisTemplate=stringRedisTemplate;}@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//1.获取请求头中的tokenString token = request.getHeader("authorization");if (StrUtil.isBlank(token)) {//4.不存在,拦截response.setStatus(401);return false;}//2.基于token获取redis中的用户String tokenKey=RedisConstants.LOGIN_USER_KEY + token;Map<Object, Object> userMap = stringRedisTemplate.opsForHash().entries(tokenKey);//3.判断用户是否存在if(userMap.isEmpty()){//4.不存在,拦截response.setStatus(401);return false;}//5.将查询到的Hash数据转为UserDTO对象UserDTO userDTO = BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false);//6.存在,保存用户信息到ThreadLocalUserHolder.saveUser( userDTO);//7.刷新token有效期stringRedisTemplate.expire(tokenKey,RedisConstants.CACHE_SHOP_TTL, TimeUnit.MINUTES);//8.放行return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {//移除用户...}
}

因为这里不能用注解注入stringRedisTemplate,要在MVC配置器哪里进行注入

@Configuration
public class MvcConfig implements WebMvcConfigurer {@Resourceprivate StringRedisTemplate stringRedisTemplate;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor(stringRedisTemplate)).excludePathPatterns("/shop/**","/shop-type/**","/upload/**","/blog/hot","/user/code" ,"/user/login");}
}

出现Long转String的报错 

在登录逻辑里面将对象转为Map时做多点工作

        //7.2将User对象转为Hash存储UserDTO userDTO=BeanUtil.copyProperties(user, UserDTO.class);Map<String, Object> userMap = BeanUtil.beanToMap(userDTO,new HashMap<>(),CopyOptions.create().setIgnoreNullValue(true).setFieldValueEditor((fieldName,fieldValue)->fieldValue.toString()));

 可以看见对应东西

 

解决登录状态刷新问题

登录状态的刷新只会在访问需要拦截的请求时才刷新,如果是不需要拦截的请求就不会刷新.

为了拦截所有请求,这里新加一个拦截器

新增刷新拦截器:

public class RefreshTokenInterceptor implements HandlerInterceptor {private StringRedisTemplate stringRedisTemplate;public RefreshTokenInterceptor(StringRedisTemplate stringRedisTemplate) {this.stringRedisTemplate=stringRedisTemplate;}@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//1.获取请求头中的tokenString token = request.getHeader("authorization");if (StrUtil.isBlank(token)) {return true;}//2.基于token获取redis中的用户String tokenKey=RedisConstants.LOGIN_USER_KEY + token;Map<Object, Object> userMap = stringRedisTemplate.opsForHash().entries(tokenKey);//3.判断用户是否存在if(userMap.isEmpty()){return true;}//5.将查询到的Hash数据转为UserDTO对象UserDTO userDTO = BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false);//6.存在,保存用户信息到ThreadLocalUserHolder.saveUser( userDTO);//7.刷新token有效期stringRedisTemplate.expire(tokenKey,RedisConstants.CACHE_SHOP_TTL, TimeUnit.MINUTES);//8.放行return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {//移除用户UserHolder.removeUser();}
}

 修改原本的登录拦截器

public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//1.判断是否需要拦截(ThreadLocal中是否有用户)if(UserHolder.getUser()==null){//没有,需要拦截response.setStatus(401);return false;}return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {//移除用户UserHolder.removeUser();}
}

MVC配置类当中

需要添加order保证刷新拦截器先执行。

@Configuration
public class MvcConfig implements WebMvcConfigurer {@Resourceprivate StringRedisTemplate stringRedisTemplate;@Overridepublic void addInterceptors(InterceptorRegistry registry) {//登录拦截器registry.addInterceptor(new LoginInterceptor()).excludePathPatterns("/shop/**","/shop-type/**","/upload/**","/blog/hot","/user/code" ,"/user/login").order(1);//刷新拦截器registry.addInterceptor(new RefreshTokenInterceptor(stringRedisTemplate)).addPathPatterns("/**").order(0);}
}

http://www.hkea.cn/news/265998/

相关文章:

  • 如何识别一个网站是否做的好谷歌关键词挖掘工具
  • 网站建设专家网店营销推广
  • 做试玩网站搜索引擎优化答案
  • 外贸家具网站百度引擎搜索网址
  • 公司网站的栏目设置肇庆seo优化
  • 如何制作一个论坛网站网络服务器配置与管理
  • 北京中国建设部网站有什么平台可以推广
  • flash网站优缺点厦门百度seo
  • 贵阳利于优化的网站百度搜索引擎推广步骤
  • 金色 网站 模板外链是什么
  • 网站有多难做如何做推广引流赚钱
  • 建设企业网站怎么样百度首页 百度
  • 热烈祝贺网站上线泉州seo代理计费
  • 网站平台建设意见长沙有实力seo优化
  • 深圳网站如何制作西安seo网站推广优化
  • 网站建设业务文案网站seo检测工具
  • 石家庄做外贸网站建设现在最好的营销方式
  • 兰州做网站公司有哪些html+css网页制作成品
  • 福州做网站的公司多少钱信息流优化
  • 群晖的网站开发百度客服怎么转人工
  • 制作网站项目流程无锡网站建设seo
  • 最好的开发网站建设价格如何搜索网页关键词
  • 做网站犯法了 程序员有责任吗网站建设合同
  • 建设部职称网站关键词优化营销
  • 做seo还要需要做网站吗百度热搜榜排行
  • 福建城市建设厅网站怎么推广一个网站
  • 机构网站建设需要交费吗关键词挖掘
  • 专业网站建设费用报价今日最新消息
  • 电商网站建设论文2022黄页全国各行业
  • 能源企业 网站建设网络营销的应用